Java 的this和super关键字
package Maoxian01; /** * 1、super是一个关键字,全部小写 * 2、super是this对比着学习 * this: * this能出现在实例方法和构造方法中 * this的语法是:"this."、"this()" * this不能使用在静态方法中 * this.大部分情况下可以省略的 * this.什么时候不能省略呢?在区分局部变量和实例变量的时候不能省略 * public void setName(String name){ * this.name = name; * } * this()只能出现在构造方法第一行,通过当前的构造方法去调用"本类"中其他的构造方法,目的是:代码复用 * super * super能出现在实例方法和构造方法中 * super的语法是:"super."、"super()" * super不能使用在静态方法中 * super.大部分情况下可以省略的 * super.什么时候不能省略呢?
* 父类和子类中有同名的属性,或者说同样的方法
* 想在子类中访问父类的,super. 不能省略
* super.属性名 【访问父类的熟悉】
* super.方法名(实参) 【访问父类的方法】
* super(实参) 【调用父类的构造方法】
* super()只能出现在构造方法第一行,通过当前的构造方法去调用"父类"中其他的构造方法,目的是:创建之类对象的时候,先初始化父类特征 * * 3、super() * 表示通过子类的构造方法调用父类的构造方法 * 模拟现实世界中的这种场景:要想又儿子,需要想父亲 * 4、重要的结论: * 当一个构造方法第一行: * 既没有this()又没有super()的话,默认会有一个super(); * 表示通过当前之类的构造方法调用父类的无参数构造方法。 * 所以必须保证父类的无参数构造方法是存在的 * 5、注意: * this()和super() 不能共存,它们都是只能出现在现在构造方法第一行 * 6、无论是怎么折腾,父类的构造方法是一定会执行的.(百分百执行) * */ public class SuperTest { public static void main(String[] args) { // 创建之类对象 /** * A类的无参数构造方法! * B类的无参数构造方法! */ new B(); } } class A{ // 建议手动的将一个类的无参数构造方法写出来 public A() { System.out.println("A类的无参数构造方法!"); } // 一个类如果没有手动提供任何构造方法,系统会默认提供一个无参数构造方法 // 一个类如果手动提供了一个构造方法,那么无参数构造系统将不再提供 public A (int i) { System.out.println("A类的有参数构造方法(int)!"); } } class B extends A { public B() { // 调用父类中有参数的构造方法 this("张三"); // super(123); System.out.println("B类的无参数构造方法!"); } public B(String name) { System.out.println("B类的有参数构造方法!"); } }
package Maoxian01; /** * 判断程序的输出结果 * A的无参数构造方法 * B类的有参数构造方法(String) * C的有参数构造执行(String,int) * C的有参数构造执行(String) * C的无参数构造执行 * * 在java语言中不管是new什么对象,最后老祖宗的Object类的无参数构造方法一定会被执行。(Object类的无参数构造方法是出处于"栈顶部")、 * 栈顶的特点: * 最后调用,但是最先执行结束 * 后进先出原则 */ public class SuperTest01 { public static void main(String[] args) { new C(); } } class A{ public A() { System.out.println("A的无参数构造方法"); } } class B extends A{ public B() { // 这个是最先调用的,但是最后结束 System.out.println("B的无参数构造方法"); } public B(String name) { System.out.println("B类的有参数构造方法(String)"); } } class C extends B{ public C() { this("张三"); System.out.println("C的无参数构造执行"); } public C(String name) { this(name,20); System.out.println("C的有参数构造执行(String)"); } public C(String name,int age) { super(name); System.out.println("C的有参数构造执行(String,int)"); } }
package Maoxian01; /** * 1、举个例子:在恰当的时间使用:super(实际参数列表); * 2、注意:在构造方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上对象只创建了一个 * 3、思考:"super(实参)"到底是干啥的? * super(实参)的作用是:初始化当前对象的父类型特征 * 并不是创建新对象,实际上对象只创建了1个 * 4、super关键字代表了什么呀? * super关键字代表的就是"当前对象"那部分父类型特征 * */ // 测试程序 public class SuperTest02 { public static void main(String[] args) { CreditAccount ca1 = new CreditAccount(); System.out.println(ca1.getActno() + "," + ca1.getBalance() + "," + ca1.getCredit()); CreditAccount ca2 = new CreditAccount("1352",10000.00,0.99); System.out.println(ca2.getActno() + "," + ca2.getBalance() + "," + ca2.getCredit()); } }
// ------------------------------------------------------------------------------------- // 账户 class Account extends Object{ // 属性 private String actno; private double balance; // 构造方法 public Account() { super(); } public Account(String actno,double balance) { this.actno = actno; this.balance = balance; } // setter and getter public String getActno() { return actno; } public void setActno(String actno) { this.actno = actno; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } } // --------------------------------------------------------------- // 信用账户 class CreditAccount extends Account{ // 属性:信誉度(诚信值) // 之类特有的一个特征,父类没有 private double credit; // 构造方法 public CreditAccount() { super(); } // 提供有参数的构造方法 public CreditAccount(String actno,double balance,double credit) { // 通过之类的构造方法调用父类的构造方法 super(actno,balance); this.credit = credit; } // setter and getter public double getCredit() { return credit; } public void setCredit(double credit) { this.credit = credit; } }
package Maoxian01; /** * 1、"this."和"super."大部分情况下都是可以省略的 * 2、 this.什么啥时候不能省略? * public void setName(String name){ * this.name = name; * } * super.什么时候不能省略? * 父中有,父中又有,如果想在之中访问"父的特征",super.不能省略 */ public class SuperTest03 { public static void main(String[] args) { // TODO Auto-generated method stub Vip v = new Vip("张三"); v.shopping(); } } class Customer{ String name; public Customer() {} public Customer(String name) { this.name = name; } } class Vip extends Customer{ // 假设子类也有一个同名属性 String name; public Vip(){} public Vip(String name) { super(name); } // super和this都不能出现在静态方法中 public void shopping() { // this表示当前对象 System.out.println(this.name + "正在购物!"); // super表示的是当前对象的父类特征,(super是this指向的那个对象中的一块空间) System.out.println(super.name + "正在购物!"); System.out.println(name + "正在购物!"); } }
package Maoxian01; /** * 通过这个测试得出结论: * super 不是引用。super也不保存的内存地址,super也不指向任何对象 * super 只是代表当前对象内部的那一块父类型的特征 * */ public class SuperTest04 { public void doSome() { // SuperTest04@15db9742 System.out.println(this); // 输出"引用"的时候,会自动调用引用的toSting()方法 // System.out.println(this.toString()); // 编译报错:需要"." // System.out.println(super); } // 静态方法,主方法 public static void main(String[] args) { SuperTest04 st = new SuperTest04(); st.doSome(); } }
package Maoxian01; /** * 在父和子中有同名的属性,或者说有相同的方法 * 如果此时想在子类中访问父中的数据,必须使用"super."加以区分 * * super.属性名 【访问父类的属性】 * super.方法名(实参) 【访问父类的方法】 * super(实参) 【调用父类的构造方法】 * */ public class SuperTest05 { public static void main(String[] args) { // TODO Auto-generated method stub Cat c = new Cat(); c.yiDong(); } } class Animal{ public void move() { System.out.println("Animal move!"); } } class Cat extends Animal{ // 对move进行重写 public void move() { System.out.println("Cat move!"); } // 单独编写一个子类特有的方法 public void yiDong() { this.move(); move(); // super. 不仅可以访问属性,也可以访问方法 super.move(); } }