java 面向对象的注意点
1. 在子类的一个构造方法中,this() 和 super() 只能存在一个,因为他两都必须被定义在构造方法的第一行,但是如果创建子类对象使用的构造方法,由于使用了this() 调用了其他子类的构造方法,导致该构造方法不能再使用super()调用父类的构造方法 ,默认情况下编译器会自动在子类的构造函数第一行添加super() , 但是如果这个构造函数中第一行是使用this() 调用其他的构造函数 ,编译器就不会再自动添加super()了,但是肯定会有一个子类的构造方法使用super()调用父类的构造方法。
class SuperClass{public int sex;public SuperClass(){}public SuperClass(int sex){this.sex = sex;}}class SonClass extends SuperClass{public int age;public String name;public SonClass(){// 这里默认会有 super() 来调用父类构造函数// 至少有一个构造函数 可以使用 super() 来调用父类构造函数}public SonClass(String name){this(); // 由于使用this()调用无参构造 不能使用super()this.name = name;}public SonClass(String name , int age){this(name);// 由于使用this(name)调用其他构造函数 不能使用super()this.age = age;}public SonClass(int sex){//这里可以使用super() 调用父类的任意构造函数super(sex);}@Overridepublic String toString() {return "SonClass{" +"sex=" + sex +", age=" + age +", name='" + name + '\'' +'}';}
}public class ThisSuperTest {public static void main(String[] args) {SonClass sonClass = new SonClass("张三");System.out.println(sonClass);}}SonClass{sex=0, age=0, name='张三'}
2.子类成员变量的显示赋值在调用super()实例化父类之后,所以在调用super()的过程中,子类成员变量的值都是默认赋值,直到super()执行完毕,才会对子类成员变量进行显示赋值。
class Super{public Super(){System.out.println("Super constructor print son age " + getAge());printAge("Super");}public int getAge(){return 50;}//这个方法会被子类覆盖,所以不会执行,会执行子类的实现public void printAge(String name){System.out.println(50);}
}class Son extends Super{private int age = 20;public Son(){super();System.out.println("son constructor print age " + age);printAge("son");}public int getAge(){return this.age;}public void printAge(String name){System.out.println(name + " call printAge method " + this.age);}
}public class MemberFieldAssignment {public static void main(String[] args) {Son son = new Son();}}运行结果:
Super constructor print son age 0 //在调用super()过程中访问age,age还是默认值
Super call printAge method 0 //在调用super()过程中访问age,age还是默认值
son constructor print age 20 //在调用super()完毕之后访问age,age已经显示赋值
son call printAge method 20 //在调用super()完毕之后访问age,age已经显示赋值
3.同名调用
1.当局部和成员同名时,使用this区分成员,this代表当前对象
2.当子类和父类的成员同名时,使用super区分父类,super代表父类空间
class SuperClass{}class SonClass extends SuperClass{public void printHashCode(SonClass this){System.out.println(this.hashCode());System.out.println(super.hashCode());}}public class ThisSuperTest {public static void main(String[] args) {SonClass sonClass = new SonClass();SonClass sonClass1 = new SonClass();sonClass.printHashCode();System.out.println();sonClass1.printHashCode();}}运行结果:
1512981843
151298184342768293
42768293说明this和super是指向同一个堆地址的
4.当子类定义了和父类一摸一样的成员变量,或者重写了父类中的成员方法,这种情况父类成员变量和成员方法 并没有被子类覆盖,只是子类对象访问时优先访问子类的成员方法或者成员变量,当子类找不到时才会去父类空间找。也可以用super直接访问父类的指定非私有成员变量和非私有成员方法
5.如果一个类纯工具类,都是静态方法,在使用时不需要创建对象,为了防止不了解的而创建对象,浪费内存,可以将默认构造方法定义为私有 private,防止创建对象。