- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试掌握 Java 中的继承窍门,并且了解到当覆盖子类中的方法(和隐藏字段)时,仍然可以使用“super”关键字从父类(super class)访问它们。
我想知道的是,“super”关键字是否应该用于非覆盖方法?
有什么区别(对于非覆盖方法/非隐藏字段)吗?
我在下面整理了一个示例。
public class Vehicle {
private int tyreCost;
public Vehicle(int tyreCost) {
this.tyreCost = tyreCost;
}
public int getTyreCost() {
return tyreCost;
}
}
和
public class Car extends Vehicle {
private int wheelCount;
public Vehicle(int tyreCost, int wheelCount) {
super(tyreCost);
this.wheelCount = wheelCount;
}
public int getTotalTyreReplacementCost() {
return getTyreCost() * wheelCount;
}
}
具体来说,假设 getTyreCost()
没有被覆盖,getTotalTyreReplacementCost()
应该使用 getTyreCost()
还是 super.getTyreCost()
?
我想知道是否应该在访问父类(super class)的字段或方法的所有实例中使用 super(以在代码中显示您正在访问父类(super class)),或者仅在被覆盖/隐藏的实例中使用(因此它们站立出去)。
最佳答案
不要使用 super
关键字来引用其他未被覆盖的方法。这会让其他试图扩展您的类的开发人员感到困惑。
让我们看一些确实以这种方式使用super
关键字的代码。这里我们有 2 个类:Dog
和 CleverDog
:
/* file Dog.java */
public static class Dog extends Animal {
private String name;
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/* file CleverDog.java */
public class CleverDog extends Dog {
public CleverDog(String name) {
super(name);
}
public void rollover() {
System.out.println(super.getName()+" rolls over!");
}
public void speak() {
System.out.println(super.getName() + " speaks!");
}
}
现在,假设您是该项目的一名新开发人员,您需要为电视上的一只聪明的狗做一些特定的行为:那只狗必须使出所有的把戏,但应该使用它虚构的电视名称。为此,您需要覆盖 getName(...)
方法...
/* file DogOnTv.java */
public class DogOnTv extends CleverDog {
String fictionalName;
public DogOnTv(String realName, String fictionalName) {
super(realName);
fictionalName = fictionalName;
}
public String getName() {
return fictionalName;
}
}
... 并落入原始开发者设置的陷阱,他们异常使用 super
关键字!
上面的代码是行不通的——因为在最初的 CleverDog
实现中,getName()
是使用 super
关键字调用的.这意味着它总是调用 Dog.getName()
- 与任何覆盖无关。因此,当您使用新的 DogOnTv
类型时...
System.out.println("Showcasing the Clever Dog!");
CleverDog showDog = new CleverDog("TugBoat");
showDog.rollover();
showDog.speak();
System.out.println("And now the Dog on TV!");
DogOnTv dogOnTv = new DogOnTv("Pal", "Lassie");
dogOnTv.rollover();
...你得到错误的输出:
Showcasing the Clever Dog!
Tugboat rolls over!
Tugboat speaks!
And now the Dog on TV!
Pal rolls over!
Pal speaks!
当您覆盖方法时,这不是通常预期的行为,因此您应该避免在不属于它的地方使用 super
关键字来造成这种混淆。
但是,如果这实际上是您想要的行为,请改用 final
关键字 - 以清楚地表明该方法不能被覆盖:
/* file CleverDog.java */
public class CleverDog extends Dog {
public CleverDog(String name) {
super(name);
}
public final String getName() { // final so it can't be overridden
return super.getName();
}
public void rollover() {
System.out.println(this.getName()+" rolls over!"); // no `super` keyword
}
public void speak() {
System.out.println(this.getName() + " speaks!"); // no `super` keyword
}
}
关于java - 访问未覆盖的父类(super class)方法时使用 'super' 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12803346/
问题比较Java,但是我想在Android中实现: 假设有 3 个或更多类相互扩展: class A { ... int color; ... } class B extend
我知道标题听起来有点奇怪,但这正是我愿意做的。简单解释:A类是B类的子类,B类也是C类的子类>. 现在,所有这些类都包含方法m()。在我的 A 类中,这是我唯一可以访问的类,因为其他类仅在运行时可用,
我有一个 UIViewController 类 A 和 B。 A 使用以下方式加载 B:[A.view addSubView B.view]。 B 有一个带有“后退”按钮的导航栏。我想在单击时返回到
我有以下(第三方)类结构。我们将调用第三方项目 ProjectSeriously,并注意我使用 System.out.println 代替其他复杂的功能(100 行代码) . class A {
在下面的代码中,我从 Game 扩展了 MyGame。我有两个问题: 我们是否需要为所有render()、dispose()、pause()调用super方法 和 resize(w,h)?很多人都没有
例如,假设我想在调用 super.viewDidLoad() 时跳过一级。所以我希望能够做这样的事情: override func viewDidLoad() { super.super.vi
public class Faculty extends Employee { public static void main(String[] args) { new Fac
假设我有: class Superclass { //fields... methodA() {...} methodB() {...} ... } class Subclass exte
这个问题在这里已经有了答案: Why is super.super.method(); not allowed in Java? (22 个答案) 关闭 9 年前。 我怀疑我想做的事情是否可行。我有
我有一个实现 Initializable 的类。 public abstract class ExampleClass implements Initializable { public vo
我想知道,我有这个大数组,是否可以只在内存中使用一次而不是每个线程一次?以 stackoverflow 上的标签为例。他们几乎从不改变,为什么不为他们留下一个内存点呢?甚至可能将该数组永久保存在内存中
假设这三个类具有这个简单的层次结构: class A { func foo() { print("A") } } class B: A { override fu
有没有办法在 TypeScript 中调用 super.super.methodName。我想避免调用super.methodName,但我想调用二祖的methodName方法。 谢谢。 最佳答案 T
这个问题已经有答案了: When do I use super()? (11 个回答) 已关闭 7 年前。 package Geometry; public abstract class Geomet
我必须执行and()在我的实现 Predicate 的业务对象上. 出现问题的代码是 and() 行调用: Predicate predicate = new M
我有一个实现接口(interface)的抽象父类(super class): public abstract class FooMatrix implements Matrix { publi
我有四个 UIView:viewA 是 Root View ,它有 viewB 作为它的 subview 。 viewB 将 viewC 作为其 subview ,而 viewC 将 viewD 作为
有什么区别: class Child(SomeBaseClass): def __init__(self): super(Child, self).__init__() 和:
我有一个通用接口(interface) interface ListList extends List> .由于某些原因,我无法转换 ListList至 List> .有什么方法可以做到吗?为什么它不
我想调用带有两个参数的父类(super class)的构造函数,所以我调用了 super(arguments),但是编译器说: “类 Person 中的构造函数 Person 不能应用于给定类型; 要
我是一名优秀的程序员,十分优秀!