英文:
Polymorphism implement forced common alterations to child's fields
问题
什么是强制抽象类的子类调用在抽象类中定义的、修改其实现的抽象变量值的最佳设计模式?
问题:
我希望根据屏幕大小按比例缩放位图。我希避免拥有多个本质上以相同方式赋值的抽象变量。例如,在这种情况下,widthScale * width
将在赋值给宽度时缩放宽度。如果我创建一个名为 scaleWidth()
的抽象方法,尽管它会向类的用户暗示他们应该实现这样的功能,但会导致在整个代码库中重复实现相同的方法。
另外,在抽象类中无法有一个缩放后的宽度变量,它会乘以2个抽象变量,因为父类的字段会在子类之前初始化;
伪代码示例:
抽象类 Image
{
抽象的整数 width;
}
类 Apple 扩展 Image
{
覆盖 整数 width = 100 * StaticAppClass.scaleFactorWidth;
}
类 Banana 扩展 Image
{
覆盖 整数 width = 50 * StaticAppClass.scaleFactorWidth;
}
因此,正如您所见,每次程序员都需要将宽度乘以 StaticAppClass.scaleFactorWidth
。这不仅不方便,而且也不够明确。这意味着程序员甚至都不会知道他必须这样做。
英文:
What's the best design pattern to force children of an abstract class to call a function defined in the abstract class that alters the value of its implemented abstract variables?
<br>
The problem:
I want to scale my bitmaps according to the screen size to keep the ratio. I want to avoid having multiple abstract variables that are essentially assigned the same way. For example in this case widthScale * width
will scale the width when assigned to the width. If I create an abstract method named scaleWidth(), though it would imply to the user of the class that they should implement such functionality, it'd cause a repetitious implementation of the same method throughout the codebase.
Also can't have a scaledWidth variable in the abstract class that multiplies 2 abstract variables since parent's fields are initialized before the childrens'
Pseudocode example:
Abstract Class Image
{
abstract int width;
}
Class Apple extends Image
{
override int width = 100 * StaticAppClass.scaleFactorWidth;
}
Class Banana extends Image
{
override int width = 50 * StaticAppClass.scaleFactorWidth;
}
So as you can see every time the programmer has to multiply the width with the StaticAppClass.scaleFactorWidth. Not only it's inconvenient also it's not explicit. Meaning, the programmer wouldn't even know he has to do that
答案1
得分: 2
绑定到成员字段是在编译时发生的,因此没有直接实现您想要的方式。也就是说,字段没有像 @Override
一样的机制。我认为最好的方法如下所示:
public static final int scaleFactor = 10;
public abstract class A {
public int getScaledWidth() {
return this.getWidth() * scaleFactor;
}
public abstract int getWidth();
}
public class B extends A {
public int width = 50;
@Override
public int getWidth() { return width; }
}
public class C extends A {
public int width = 100;
@Override
public int getWidth() { return width; }
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.getScaledWidth());
C c = new C();
System.out.println(c.getScaledWidth());
}
通过这种结构,在编写 A
的新特化时,开发人员将被要求提供 getWidth()
方法,从而强制他们考虑所需的内容。
英文:
Binding to member fields happens at compile time, so there's no way to directly do what you want. I.e. there's no @Override
for fields. I believe the best way is as follows:
public static final int scaleFactor = 10;
public abstract class A
{
public int getScaledWidth()
{
return this.getWidth() * scaleFactor;
}
public abstract int getWidth();
}
public class B extends A
{
public int width = 50;
@Override
public int getWidth() { return width; }
}
public class C extends A
{
public int width = 100;
@Override
public int getWidth() { return width; }
}
public static void main(String[] args)
{
B b = new B();
System.out.println(b.getScaledWidth());
C c = new C();
System.out.println(c.getScaledWidth());
}
With this structure, when writing a new specialization of A
, the developer will be required to provide getWidth()
, forcing them to consider what is needed.
答案2
得分: 1
你难道不能让子类分配它们的宽度值,然后让超类实现一个``scaledWidth``获取器吗?(你说过你用的是 Kotlin,我也用 Kotlin 模式来举个例子!)
abstract class Image {
abstract val width: Int
val scaleFactorWidth = 2
fun getScaledWidth() = width * scaleFactorWidth
}
class Banana : Image() {
override val width = 100
}
这样,子类需要实现的唯一内容就是``width``属性(我是指最好将其传递到构造函数中,但属性可能太多了)。缩放宽度是通过getter函数访问的,因此在任何人调用它之前,所有内容都已初始化。
如果你使用的是 Kotlin,甚至可以这样写:
val scaledWidth by lazy { width * scaledWidth }
它只存储一个值,但会在首次访问时计算它(仅计算一次)- 只要不是在``Image``超类的初始化期间访问它,就应该没问题。
英文:
Couldn't you just have the subclasses assign their width values, and have the superclass implement a scaledWidth
getter? (You said Kotlin and I'm in Kotlin mode so here's my example!)
abstract class Image {
abstract val width: Int
val scaleFactorWidth = 2
fun getScaledWidth() = width * scaleFactorWidth
}
class Banana : Image() {
override val width = 100
}
that way the only thing the subclasses need to implement is a width
property (I mean it would be better to pass them into the constructor but there might be too many properties for that). The scaled width is accessed through a getter function, so it's all initialised by the time anyone calls it.
If you are in Kotlin you could even do
val scaledWidth by lazy { width * scaledWidth }
which stores a single value, but calculates it (once) when it's first accessed - so long as that's not during the initialisation of the Image
superclass, you should be ok?
答案3
得分: -1
如果我理解正确,width 是一个对于每个实现都不同的常量?
我会这样做:
在抽象类中:
public abstract int getWidth();
在实现类中:
@Override
public int getWidth() {
return value;
}
英文:
If I understand well, width is a constant different for each implementation?
I would do something like that:
In the abstract class:
public abstract int getWidth();
In the implementations:
@Override
public int getWidth() {
return value;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论