【发布时间】:2011-04-30 17:11:02
【问题描述】:
关键字this和super有什么区别?
两者都用于访问类的构造函数,对吧?谁能解释一下?
【问题讨论】:
关键字this和super有什么区别?
两者都用于访问类的构造函数,对吧?谁能解释一下?
【问题讨论】:
让我们考虑一下这种情况
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void anotherEat() {
super.eat();
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eat();
d.anotherEat();
}
}
输出将是
animal : eat
dog : eat
animal : eat
第三行打印“animal:eat”,因为我们调用的是super.eat()。如果我们调用this.eat(),它会打印为“dog:eat”。
【讨论】:
super用于访问基类的方法,this用于访问当前类的方法。
扩展概念,如果你写super(),它指的是基类的构造函数,如果你写this(),它指的是你正在编写这段代码的那个类的构造函数。
【讨论】:
this 是对类型为当前类的对象的引用,super 是对类型为父类的对象的引用。
在构造函数中,this() 调用当前类中定义的构造函数。 super() 调用父类中定义的构造函数。构造函数可以在任何父类中定义,但它将引用最接近当前类的重写。以这种方式调用其他构造函数只能作为构造函数的第一行。
调用方法的工作方式相同。调用this.method() 会调用当前类中定义的方法,而super.method() 将调用父类中定义的相同方法。
【讨论】:
根据您的问题,我认为您实际上是在询问 this 和 super 在构造函数链接中的使用;例如
public class A extends B {
public A(...) {
this(...);
...
}
}
对
public class A extends B {
public A(...) {
super(...);
...
}
}
区别很简单:
this 表单链接到当前类中的构造函数;即在A 类中。
super 表单链接到直接超类中的构造函数;即在B 类中。
【讨论】:
this 引用 current 类。 super 指的是当前类的父类(称为super 关键字)。
通过this,它允许您访问当前类的方法/属性(包括它自己的私有方法/属性)。
super 允许您访问父(基)类的公共/受保护方法/属性。您看不到父级的私有方法/属性。
【讨论】:
base 和 derived 类之类的词,而不是 based 和 derived 对象。也许新文学区分了差异。
注意:
我们只能在构造函数中使用 super() 和 this() 不能在其他任何地方使用,任何 尝试这样做会导致编译时错误。
我们必须保留 super() 或 this() 作为 构造函数,但不能同时进行。
注意:我们可以在类中的任何地方使用它们,除了静态区域(静态块或方法),任何 尝试这样做会导致编译时错误。
【讨论】:
this 用于访问当前对象的方法和字段。因此,例如,它在静态方法中没有任何意义。
super 允许访问超类中的非私有方法和字段,并且只能从类的构造函数中访问构造函数。
【讨论】:
在编写代码时,您通常不想重复自己。如果您有一个可以用各种数量的参数构造的类,避免重复自己的常见解决方案是简单地调用另一个构造函数,并在缺少的参数中使用默认值。对此只有一个烦人的限制——它必须是声明的构造函数的第一行。示例:
MyClass()
{
this(default1, default2);
}
MyClass(arg1, arg2)
{
validate arguments, etc...
note that your validation logic is only written once now
}
至于super() 构造函数,与super.method() 访问不同,它必须是构造函数的第一行。之后,它非常类似于this() 构造函数,DRY(不要重复自己),如果您扩展的类有一个构造函数可以执行您想要的某些操作,那么使用它然后继续构造您的对象,例如:
YourClass extends MyClass
{
YourClass(arg1, arg2, arg3)
{
super(arg1, arg2) // calls MyClass(arg1, arg2)
validate and process arg3...
}
}
附加信息:
即使你没有看到它,默认的无参数构造函数总是首先调用super()。示例:
MyClass()
{
}
等价于
MyClass()
{
super();
}
我看到很多人提到在方法和变量上使用 this 和 super 关键字 - 都很好。请记住,构造函数对其使用有独特的限制,最值得注意的是它们必须是声明的构造函数的第一条指令,并且您只能使用一个。
【讨论】:
this关键字用于调用同一类中的构造函数(其他重载的构造函数)
语法:this(参数列表); //兼容args list在同一个类的其他构造函数
super 关键字用于调用超类中的构造函数。
语法: super(参数列表); //兼容超类构造函数中的args list。
例如:
public class Rect {
int x1, y1, x2, y2;
public Rect(int x1, int y1, int x2, int y2) // 1st constructor
{ ....//code to build a rectangle }
}
public Rect () { // 2nd constructor
this (0,0,width,height) // call 1st constructor (because it has **4 int args**), this is another way to build a rectangle
}
public class DrawableRect extends Rect {
public DrawableRect (int a1, int b1, int a2, int b2) {
super (a1,b1,a2,b2) // call super class constructor (Rect class)
}
}
【讨论】: