Zee*_*han 115 java oop inheritance static protected
我正在经历这个问题有没有办法在Java中覆盖类变量? 36条赞成票的第一条评论是:
如果你看过
protected static
,跑.
任何人都可以解释为什么protected static
不赞成?
Tim*_*m B 79
这比直接问题更具风格性.它表明你没有正确地思考课程的内容.
想想是什么static
意思:
这个变量存在于类级别,它不是为每个实例单独存在,并且它在扩展我的类中没有独立存在.
想想是什么protected
意思:
这个类可以看到这个变量,同一个包中的类和扩展我的类.
这两个含义并不完全相互排斥,但它非常接近.
我可以看到你可以使用这两个的唯一情况在一起,如果你有这样的设计被延伸再延伸的类可以修改使用原定义的常量行为的抽象类.尽管如此,这仍然是一个非常微弱的原因,因为你几乎肯定会更好地将常数公之于众.这只会让一切变得更加清洁,并且让人们可以更加灵活地进行分类.
要扩展并解释第一点 - 尝试此示例代码:
public class Program {
public static void main (String[] args) throws java.lang.Exception {
System.out.println(new Test2().getTest());
Test.test = "changed";
System.out.println(new Test2().getTest());
}
}
abstract class Test {
protected static String test = "test";
}
class Test2 extends Test {
public String getTest() {
return test;
}
}
Run Code Online (Sandbox Code Playgroud)
你会看到结果:
test
changed
Run Code Online (Sandbox Code Playgroud)
请亲自尝试:https://ideone.com/KM8u8O
类Test2
是能够访问静态成员test
从Test
无需限定名称-但它没有继承或让自己的副本.它正在查看完全相同的变量.
Vin*_*igh 31
它不赞成因为它是矛盾的.
创建变量protected
意味着它将在包中使用,或者它将在子类中继承.
使变量static
成为类的成员,消除继承它的意图.这只留下在包中使用的意图,我们package-private
为此(没有修饰符).
我能找到这个有用的唯一情况是,如果你是宣称应该用于启动应用程序(如JavaFX的的一类Application#launch
,只希望能够从一个子类启动,如果这样做,确保方法也final
给不允许隐藏.但这不是"常态",并且可能通过添加新方法来启动应用程序来防止增加更多复杂性.
要查看每个修饰符的访问级别,请参阅:Java教程 - 控制对类成员的访问
Mar*_*o13 13
我没有看到为什么这应该不赞成的特殊原因.可能总是存在实现相同行为的替代方案,并且取决于实际结构,这些替代方案是否比受保护的静态方法"更好".但是受保护的静态方法至少可以合理的一个例子如下:
(编辑分成单独的包,以使protected
更清晰的使用)
package a;
import java.util.List;
public abstract class BaseClass
{
public Integer compute(List<Integer> list)
{
return computeDefaultA(list)+computeDefaultB(list);
}
protected static Integer computeDefaultA(List<Integer> list)
{
return 12;
}
protected static Integer computeDefaultB(List<Integer> list)
{
return 34;
}
}
Run Code Online (Sandbox Code Playgroud)
源于此:
package a.b;
import java.util.List;
import a.BaseClass;
abstract class ExtendingClassA extends BaseClass
{
@Override
public Integer compute(List<Integer> list)
{
return computeDefaultA(list)+computeOwnB(list);
}
private static Integer computeOwnB(List<Integer> list)
{
return 56;
}
}
Run Code Online (Sandbox Code Playgroud)
另一个派生类:
package a.b;
import java.util.List;
import a.BaseClass;
abstract class ExtendingClassB extends BaseClass
{
@Override
public Integer compute(List<Integer> list)
{
return computeOwnA(list)+computeDefaultB(list);
}
private static Integer computeOwnA(List<Integer> list)
{
return 78;
}
}
Run Code Online (Sandbox Code Playgroud)
该protected static
修改肯定可以在这里有道理:
static
,因为它们不依赖于实例变量.它们不是直接用作多态方法,而是"实用"方法,它们提供作为更复杂计算的一部分的默认实现,并充当实际实现的"构建块".public
,因为它们是一个实现细节.他们不能private
因为他们应该被扩展类调用.它们也不能具有"默认"可见性,因为在其他包中扩展类将无法访问它们.(编辑:人们可以假设原始评论仅涉及字段,而不是方法 - 然而,它太过笼统)
静态成员不是继承的,和受保护成员只对亚类(和当然包含类)可见,因此protected static
具有相同的可见性static
,这表明由编码器的误解.
实际上,根本没有什么错protected static
。如果您确实想要包和声明类的所有子类可见的静态变量或方法,请继续进行操作protected static
。
有些人通常避免使用protected
各种原因,有些人认为非最终static
变量应该通过各种手段来避免(我个人后者在一定程度上同情),所以我猜的组合protected
和static
必须看坏^ 2到那些属于这两个群体。