![]() |
1
451
它违反了封装。您不应该能够绕过父类的行为。有时可以绕过你的 拥有 类的行为(尤其是在同一方法中)而不是父类的行为。例如,假设我们有一个基“项集合”,一个子类表示“红色项集合”,另一个子类表示“大红色项集合”。有以下条件是有意义的:
很好-Reditems总是相信它包含的项目都是红色的。现在假设我们 是 能够调用super.super.add():
现在我们可以添加任何我们喜欢的,和
这有道理吗? |
![]() |
2
64
我认为乔恩·斯基特的回答是正确的。我想补充一点,你
可以
通过强制转换从超类的超类访问阴影变量
产生输出: x= 3 super.x= 2 ((T2)this).x= 2 ((T1)this).x= 1 ((I)this).x= 0 (示例来自 JLS ) 但是,这对方法调用不起作用,因为方法调用是根据对象的运行时类型确定的。 |
![]() |
3
37
我认为下面的代码允许在大多数情况下使用super.super…super.method()。 (即使这样做很糟糕) 简而言之
用途:
|
![]() |
4
10
我没有足够的声誉来发表评论,所以我会将此添加到其他答案中。 乔恩·斯基特以一个很好的例子回答了问题。马特B有一点:不是所有的超类都有超类。如果你称一个超级的超级没有超级,你的代码就会被破坏。 面向对象的编程(Java)是关于对象,而不是函数。如果您想要面向任务的编程,选择C++或其他东西。如果你的对象不适合它的超级类,那么你需要将它添加到“祖父母类”,创建一个新类,或者找到另一个它适合的超级类。 就我个人而言,我发现这种局限性是Java最大的优势之一。与我使用的其他语言相比,代码有点死板,但我总是知道该期待什么。这有助于Java的“简单而熟悉”的目标。在我看来,叫super.super并不简单,也不熟悉。也许开发人员也有同样的感受? |
![]() |
5
8
有一些很好的理由这样做。您可能有一个子类,该子类有一个方法实现不正确,但父方法实现正确。因为它属于第三方库,所以您可能无法/不愿意更改源。在这种情况下,您希望创建一个子类,但要重写一个方法来调用super.super方法。 如其他一些海报所示,通过反射可以做到这一点,但应该可以做到 (supersuperclass this).themethod(); 我现在正在处理这个问题-快速解决方法是将超类方法复制并粘贴到子类方法中:) |
![]() |
6
7
除了其他人提出的非常好的观点外,我认为还有另一个原因:如果超类没有超类呢?
因为每个类都是自然延伸的(至少)
我认为不允许这样做的主要原因是它违反了封装,但这可能也是一个很小的原因。 |
![]() |
7
3
我想如果你重写一个方法并想要它的所有超类版本(比如说
我认为这只是很少有意义(如果有的话)。我想不出在哪种情况下调用某个任意超类的方法版本。我不知道在Java中是否有可能。它可以在C++中完成:
|
![]() |
8
2
大概吧,因为它不经常使用。我能看到使用它的唯一原因是,如果您的直接家长已经覆盖了某些功能,并且您正试图将其恢复到原始状态。 在我看来,这违背了OO原则,因为这个班的直系父母应该比祖父母更接近你的班。 |
![]() |
9
2
如果可能的话,我会把super.super方法体放在另一个方法中。
或者,如果您无法更改超级类,可以尝试以下操作:
在这两种情况下,
“我是超级超级”的结果 |
![]() |
10
1
似乎至少可以使用反射来获取超类的超类的类,尽管不一定是它的实例;如果这可能有用,请考虑下面的javadoc: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getSuperclass() |
![]() |
11
1
运行: 一 生成成功(总时间:0秒) |
![]() |
12
1
我曾经遇到过这样的情况,当体系结构要在一个公共的CustomBaseClass中构建公共功能时,该类代表几个派生类实现。 但是,我们需要绕过特定派生类的特定方法的公共逻辑。在这种情况下,我们必须使用super.super.methodx实现。 我们通过在CustomBaseClass中引入一个布尔成员来实现这一点,该成员可用于有选择地推迟自定义实现,并在需要时向默认框架实现让步。
然而,在框架和应用程序中遵循良好的体系结构原则,我们可以通过使用HASA方法而不是ISA方法轻松避免这种情况。但在任何时候,期望设计良好的体系结构到位都不是很实际,因此需要摆脱可靠的设计原则,引入这样的黑客。 只是我的2美分… |
![]() |
13
1
@乔恩·斯基特解释得很好。 IMO如果有人想调用super.super方法,那么必须要忽略直接父对象的行为,但要访问父对象的行为。 这可以通过实例来实现。以下代码
这是司机班,
其输出将是
在这种情况下,B类printclass行为将被忽略。 我不确定这是否是实现super.super的理想或良好实践,但它仍然有效。 |
![]() |
14
1
看 this Github项目,尤其是ObjectHandle变量。这个项目展示了如何实际而准确地调用孙子的祖父母方法。 为了防止链接被破坏,下面是代码:
快乐编码!!!!! |
![]() |
15
0
如果您认为需要超类,可以在该类的变量中引用它。例如:
应该打印出来:
|
![]() |
16
0
在我看来,这是一个干净的方法
输出:
|
![]() |
17
0
当不能更改基类的代码时,调用super.super.method()是有意义的。这通常在扩展现有库时发生。 先问问你自己,你为什么要延长这门课?如果答案是“因为我不能更改它”,那么您可以在应用程序中创建精确的包和类,并重写调皮的方法或创建委托:
例如,您可以创建 org.springframework.test.context.junit4.springjunit4类服务器 应用程序中的类,因此该类应在JAR中的实际类之前加载。然后重写方法或构造函数。 注意: 这是绝对黑客,强烈建议不要使用,但它是工作的!使用这种方法是危险的,因为类加载器可能有问题。此外,每次更新包含被覆盖类的库时,这可能会导致问题。 |
![]() |
18
0
我认为这是一个破坏继承协议的问题。
你就是不能从超级班里挑选 .
但是,当您觉得有必要打电话时,可能会发生这种情况
|
![]() |
19
0
在C中,您可以调用类似以下任何祖先的方法:
你也可以在Delphi中这样做:
但在爪哇,你只能通过一些齿轮来实现这种专注。一种可能的方法是:
objc.doit()结果输出:
|
![]() |
20
-1
这很简单。例如: B的C子类和A的B子类。例如,这三个子类都有methodname()方法。 公共抽象类A{
} 公共B类扩展A{
} 公共C类扩展B{
} 运行C类输出将为: 甲类 C类 代替输出: 甲类 乙类 C类 |
![]() |
21
-1
输出:以爷爷的名义打印 |
![]() |
22
-1
关键字super只是在超类中调用方法的一种方法。 在Java教程中: https://docs.oracle.com/javase/tutorial/java/IandI/super.html 如果方法重写了其超类的某个方法,则可以通过使用关键字super来调用被重写的方法。不要相信它是超级物体的参考!!!!不,它只是一个在超类中调用方法的关键字。 下面是一个例子:
当你打电话
|
![]() |
Loic · 从超类型解析隐式参数 8 年前 |
![]() |
NiklasZeroZero · 方法不重写其超类中的方法 9 年前 |
![]() |
Alex Salauyou · 如何找到两个非接口类中最近的公共超类 9 年前 |
|
and0 · 访问包私有子类的实例作为其公共超类 9 年前 |
![]() |
basti12354 · 将方法放入AsyncTask 11 年前 |