[英]The use of protected member variables from child class and abstract parent
According to our professor, the use of protected visibility should be avoided at all costs. 根据我们的教授的说法,应不惜一切代价避免使用受保护的可见性。 However, I'm a little puzzled as to why.
但是,我对为什么有些疑惑。 Say We have this for example:
说我们有这个例子:
public abstract class Animal {
private int maxSpeed;
public Animal() {}
public abstract void setMaxSpeed();
}
Where each Animal
would have a max speed that would need to be defined later in the child class. 每个
Animal
具有最大速度的位置,稍后需要在子类中定义最大速度。 However, throwing this in: 但是,将其抛出:
public class Tutrle extends Animal {
public Tutrle() {
}
@Override
public void setMaxSpeed() {
}
}
There is no way to be able to access the maxSpeed
variable from within the overridden setMaxSpeed()
method. 无法从覆盖的
setMaxSpeed()
方法内访问maxSpeed
变量。 Although a solution would be to set maxSpeed
via the constructor of the Animal
class, wouldn't be better to set the maxSpeed
variable to protected
and have it accessible to all child sub-classes to be defined later? 尽管一种解决方案是通过
Animal
类的构造函数设置maxSpeed
,但将maxSpeed
变量设置为protected
并让以后所有定义的所有子子类都可以访问它不是更好吗?
Since the maxSpeed
member is defined in the Animal
class, it makes more sense for that class to have a non-abstract method that would set it : 由于
maxSpeed
成员是在Animal
类中定义的,因此该类具有可以对其进行设置的非抽象方法就更有意义了:
public void setMaxSpeed(int maxSpeed)
{
this.maxSpeed = maxSpeed;
}
The sub-classes (such as Turtle
) may override this method to add logic, but they should call the base class to set the value. 子类(例如
Turtle
)可以重写此方法以添加逻辑,但是它们应调用基类来设置值。
@Override
public void setMaxSpeed(int maxSpeed)
{
if (maxSpeed > 5)
throw new SomeException();
super.setMaxSpeed(maxSpeed);
}
If setMaxSpeed()
stays abstract, it would make more sense for each sub-class that implements this method to have its own maxSpeed
member. 如果
setMaxSpeed()
保持抽象状态,则对于实现此方法的每个子类来说,拥有自己的maxSpeed
成员会更有意义。
In order to access maxSpeed
attribute from subclasses, you could: 为了从子类访问
maxSpeed
属性,您可以:
protected
(your professor doesn't seem to like this very much, but I think he's lacking a suitable explanation) protected
(您的教授似乎不太喜欢它,但是我认为他缺乏适当的解释) getMaxSpeed()
method in the superclass: if knowing the max speed from outside the hierarchy is needed, declare it as public
; getMaxSpeed()
方法:如果需要从层次结构外部知道最大速度,则将其声明为public
; otherwise, declare it as protected
, so that subclasses (specific animals, such as your Turtle
) can know what their max speed is. protected
,以便子类(特定动物,例如Turtle
)可以知道其最大速度。 I agree with @Eran in that the setMaxSpeed()
method shouldn't be declared as abstract
in the Animal
superclass, and subclasses could call super.setMaxSpeed()
from their own setMaxSpeed
method if they need to do specific processing when their max speed is being set. 我同意@Eran的观点,即在
Animal
超类中不应将setMaxSpeed()
方法声明为abstract
方法,如果子类在最大速度为0时需要进行特定处理,则可以从其自己的setMaxSpeed
方法中调用super.setMaxSpeed()
。被设置。
Regarding why using protected
is claimed to be 'avoided at all costs', or dangerous, etc, please refer to this amazing newsletter's article . 关于为什么声称“不惜一切代价避免使用
protected
”或危险的等原因,请参阅此惊人的时事通讯文章 。 My personal opinion is that it is wrong to make such claims, or at least, an overreaction. 我个人的观点是,做出这样的主张,或者至少是过度反应是错误的。 However, as explained in the article:
但是,如文章中所述:
We should try to only call either private or final methods from inside our constructors.
我们应该尝试仅从构造函数内部调用私有方法或最终方法。 The reason is that Java always calls the most derived method, which means we could call a method on a half-initialized object.
原因是Java总是调用最派生的方法,这意味着我们可以在半初始化对象上调用方法。
This means that if you call a protected
method from within the constructor of your superclass, and that if the protected
method is overriden in one of the subclasses, then the code within that method would run before the rest of the class was fully initialized, which might lead to nasty errors: 这意味着,如果您从父类的构造函数中调用
protected
方法,并且如果在子类之一中重写了protected
方法,则该方法中的代码将在该类的其余部分完全初始化之前运行。可能导致讨厌的错误:
class Animal {
protected int maxSpeed;
protected SomeClass someClass;
protected Animal(int maxSpeed, SomeClass someClass) {
this.setMaxSpeed(maxSpeed); // call to subclass method
this.someClass = someClass;
}
public abstract void setMaxSpeed(int maxSpeed); // could also be protected
}
class Turtle extends Animal {
@Override
public void setMaxSpeed(int maxSpeed) {
if (this.someClass.checkIfMaxSpeedMustBeDoubled()) { // throws NPE
this.maxSpeed = maxSpeed * 2;
} else {
this.maxSpeed = maxSpeed;
}
}
}
In this very simple example, this.someClass.checkIfMaxSpeedMustBeDoubled()
throws a NullPointerException
because this.someClass
has not been yet initialized in the Animal
superclass. 在这个非常简单的示例中,
this.someClass.checkIfMaxSpeedMustBeDoubled()
引发NullPointerException
因为this.someClass
尚未在Animal
超类中初始化。 This kind of error is very common when using protected
members, but claiming that protected
should be avoided is ridiculous. 使用
protected
成员时,这种错误非常普遍,但是声称应该避免protected
是荒谬的。 Just be careful and only call either private
or final
methods from within the superclass' constructor, and you'll be OK. 请小心,仅从超类的构造函数中调用
private
方法或final
方法,您会没事的。
It is depends on requirement, If you want maxSpeed
variable should be present in your all subclasses then put that variable in super class and then reuse that variable in subclass. 这取决于需求,如果希望
maxSpeed
变量应出现在所有子类中,则将该变量放在maxSpeed
类中,然后在子类中重用该变量。 for that you have to initialize that variable through subclass constructor and change modifier to protected for that variable. 为此,您必须通过子类构造函数初始化该变量,并将该变量的修饰符更改为protected。
But its better to create variable in your subclass if those are related to your subclass only, 但是,如果子类仅与您的子类相关,则最好在子类中创建变量,
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.