貌似感冒的时候脑子比平时还好用,虽然有点晕呼呼的……
说到java中的this和super,我们先来说说构造器和方法的区别吧!this和super在构造器中相当常见,偶尔也出现在方法中 ,但是由于构造器和方法不是一回事,那么this和super的含义也大不相同。
构造器,是为了创建一个类的实例,一般使用在创建对象的时候,如:
A a = new A();
然而,方法的作用是为了执行java代码。
这两者的区别还不止这些,可使用的修饰符、返回值和命名也有差异。
和方法一样,构造器可以有任何访问的修饰符,如public、protected、private或没有修饰符(通常被package和friendly调用)
不同于方法的是,构造器不能有一下非访问性质的修饰符:abstract、final、native、static和synchronized.
这两者的返回值是最大的区别之一,方法能返回任何类型的值或无返回值(void),构造器没有返回值,也不需要void.
至于两者的命名,除了构造器必须和类名相同之外没有其他硬性要求。但是按照习惯,类名通常第一个字母大写,故构造器的命名也有大写字母开始,方法则习惯用小写开始。
既然已经了解了构造器和方法的区别,下面我相信对this和super的理解额不难。
“this”的用法:
1.构造器使用this指向同一个类中不同参数列表中的另外一个构造器,比如:
public class A{
String str;
public A(String str2){
str = str2;
}
public A(){
this("freedom");
}
}
@Test
public void test(){
A a1 = new A("test");
A a2 = new A();
System.out.println(a1+" "+a2);
}
/*运行结果:test freedom */
源码分析:A有两个不同的构造器,第一个是给类的成员str赋值;第二个直接调用第一个构造器,给str一个初始值。
注意:在构造器中,使用this关键字的话,必须放在第一行,否则会导致Compile Error。
2.方法引用this指向正在执行方法的类的实例。静态方法不能使用this关键字(静态方法不属于类的实例)。
“super”的使用方法:
构造器和方法使用super都是为了指向超类,但是用的方法不一样。
方法用这个关键字去执行被重载的超类中的方法。比如:
public class B{
public void getValue(){
System.out.println("B test");
}
}
public class C extends B{
public void getValue(){
System.out.println("C test");
supper.getValue();
}
}
@Test
public void test(){
C c = new C();
}
/*输出结果:C Test
B Test
*/
在上面的例子中,使用super.getValue()去调用超类B中被重载的方法。
构造器使用super去调用超类中的构造器。而且这行代码必须放在第一行,否则编译将出错。看下面的例子:
public class Father {
public Father() {}
}
public class Child extends Father{
Child() {
super();
}
}
在上面这个没有什麽实际意义的例子中,构造器 Child()包含了 super,它的作用就是将超类中的构造器SuperClassDemo实例化,幷加到 Child类中。
编译器自动加入代码到构造器,对于这个,很容易混淆。当我们写一个没有构造器的类,编译的时候,编译器会自动加上一个不带参数的构造器,例如:
public class Test{}
编译后将如下代码:
public class Test{
Test() {}
}
在构造器的第一行,没有使用super,那麽编译器也会自动加上,例如:
public class TestSuper {
TestSuper() {}
}
编译器会加上代码,如下:
public class TestSuper{
TestSuper() {
super;
}
}
仔细想一下,就知道下面的代码
public class Test{}
经过会被编译器加代码形如:
public class Test{
Test() {
super;
}
}
继承: 构造器是不能被继承的。子类可以继承超类的任何方法。看看下面的代码:
public class Test{
public void sayHi {
system.out.println("Hi");
}
public Test() {}
}
public class Child extends Test{
}
类 Child自动继承了父类中的sayHi方法,但是,父类中的构造器 Test()却不能被继承。