继承–相关操作
-
继承合适及使用
-
Employee类
package cn.xiaoge.day09.demo01; // 定义一个父类: 员工 public class Employee { public void method() { System.out.println("方法执行! "); } }
-
Teacher类
package cn.xiaoge.day09.demo01; // 定义了一个员工的子类: 讲师 public class Teacher extends Employee { }
-
Assistant类
package cn.xiaoge.day09.demo01; // 定义了员工的另一个子类: 助教 public class Assistant extends Employee { }
-
执行路口
package cn.xiaoge.day09.demo01; /* 在继承关系中, "子类就是父类". 也就是说, 子类可以被当做父类看待. 列如父类是员工, 子类是讲师, 那么"讲师就是一个员工". 关系: is-a. 定义父类的格式: (一个普通的类定义) public class 父类名称{ // .... } 定义子类的格式: public class 子类名称 extends 父类的名称{ // .... } */ public class Demo01Extends { public static void main(String[] args) { // 创建了一个子类对象 Teacher teacher = new Teacher(); // Teacher类当中虽然什么都没写, 但是会继承来自父类的method方法 teacher.method(); // 创建另一个子类助教对象 Assistant assistant = new Assistant(); assistant.method(); } } // 运行结果 方法执行! 方法执行!
-
-
成员变量重名访问方式
-
Zi类
package cn.xiaoge.day09.demo02; public class Zi extends Fu { int numZi = 20; int num = 200; public void methodZi() { // 因为本类当中有num, 所以这里用的是本类的num. System.out.println(num); } }
-
Fu类
package cn.xiaoge.day09.demo02; public class Fu { int numFu = 10; int num = 100; public void methodFu() { // 使用的是本类当中的, 不回向下找子类的. System.out.println(num); } }
-
执行路口
package cn.xiaoge.day09.demo02; /* 在父子类的继承关系中, 如果成员变量重名, 则创建子类对象时, 访问有两种方式: 直接通过子类对象访问成员变量 等号左边是谁, 就优先是谁, 没有就像上找. 间接通过成员方法访问成员变量: 该方法属于谁, 就优先用谁, 没有则向上找. */ public class Demo01ExtendsField { public static void main(String[] args) { Fu fu = new Fu(); // 创建父类对象 System.out.println(fu.num); // 只能使用父类的东西, 没有任何子类内容 System.out.println("========================"); Zi zi = new Zi(); System.out.println(zi.numFu); // 10 System.out.println(zi.numZi); // 20 System.out.println("========================"); // 等号左边是谁, 就优先用谁. System.out.println(zi.num); // 优先子类, 200 // System.out.println(zi.abc); // 到处都没有, 编译报错! System.out.println("========================"); // 这个方法子类的, 优先用子类的, 没有在向上找. zi.methodZi(); // 200 // 这个方法是在父类当中定义的. zi.methodFu(); // 100 } } // 运行结果 100 ======================== 10 20 ======================== 200 ======================== 200 100
-
-
this和super访问成员变量
-
Fu类
package cn.xiaoge.day09.demo03; public class Fu { int num = 10; }
-
Zi类
package cn.xiaoge.day09.demo03; public class Zi extends Fu { int num = 20; public void method() { int num = 30; System.out.println(num); // 30 局部变量 System.out.println(this.num); // 20 本类的成员变量 System.out.println(super.num); // 10 父类的成员变量 } }
-
执行路口
package cn.xiaoge.day09.demo03; /* 局部变量: 直接写成员变量名 本类的成员变量: this.成员变量名 父类的成员变量: super.成员变量名 */ public class Demo01ExtendsField { public static void main(String[] args) { Zi zi = new Zi(); zi.method(); } } // 运行结果 30 20 10
-
-
重写重载
-
Fu类
package cn.xiaoge.day09.demo04; public class Fu { public void methodFu() { System.out.println("父类方法执行"); } public void method() { System.out.println("父类重名方法执行"); } }
-
Zi类
package cn.xiaoge.day09.demo04; public class Zi extends Fu { public void methodZi() { System.out.println("子类方法执行"); } public void method() { System.out.println("子类重名方法执行"); } }
执行路口
package cn.xiaoge.day09.demo04; /* 在父类的继承关系中, 创建子类对像, 访问成员方法的规则: 创建的对象是谁, 就优先用谁, 如果没有就向上找. 注意事项: 无论是成员方法还是成员变量, 如果没有都是向上找父类, 绝对不会向下找子类的. 重写(Override) 概念: 在继承关系当中, 方法的名称一样, 参数列表也一样. 重写(Override): 方法的名称一样, 参数列表[也一样].覆盖、复写. 重载(OverLoad): 方法的名称一样, 参数列表[不一样] 方法的覆盖从写特点: 创建的是子类对象, 则优先用子类方法. */ public class Demo01ExtendsMethod { public static void main(String[] args) { Zi zi = new Zi(); zi.methodFu(); zi.methodZi(); // 创建的是new了子类对象, 所以优先用子类方法. zi.method(); } } // 运行结果 父类方法执行 子类方法执行 子类重名方法执行
-
-
Override
-
Fu类
package cn.xiaoge.day09.demo05; public class Fu { public void method() { } }
-
Zi类
package cn.xiaoge.day09.demo05; public class Zi extends Fu { @Override public void method() { } }
-
执行路口
package cn.xiaoge.day09.demo05; /* 方法覆盖重写的注意事项: 1. 必须保证父子类之间的名称相同, 参数列表也相同. @Override: 写在方法前面, 用来检测是不是有效的正确覆盖重写. 这个注释就算不写, 只要满足要求, 也是正确的方法覆盖重写. 2. 子类方法的返回值必须[小于等于]父类方法的返回值范围. 小扩展提示: java.lang.Object类是所有类的公共最高父类(祖宗类), java.lang.String就是Object的子类 3. 子类方法的权限必须[大于等于]父类方法的权限修饰符. 小扩展提示: public > protected > (default) > private 备注: (default)不是关键字default, 而是什么都不写, 留空. */ public class Demo01Override { }
-
-
手机案列
-
Phone类
package cn.xiaoge.day09.demo06; // 本来的老款手机 public class Phone { public void call() { System.out.println("打电话"); } public void send() { System.out.println("发短信"); } public void show() { System.out.println("显示号码"); } }
-
NewPhone类
package cn.xiaoge.day09.demo06; // 定义一个新手机, 使用老手机作为父类 public class NewPhone extends Phone { @Override public void show() { super.show(); // 把父类的show方法拿过来重复利用 // 自己子类再来添加更多内容 System.out.println("显示姓名"); System.out.println("显示头像"); } }
-
执行路口
package cn.xiaoge.day09.demo06; public class Demo01Phone { public static void main(String[] args) { Phone phone = new Phone(); phone.call(); phone.send(); phone.show(); System.out.println("====================="); NewPhone newPhone = new NewPhone(); newPhone.call(); newPhone.send(); newPhone.show(); } } // 运行结果 打电话 发短信 显示号码 ===================== 打电话 发短信 显示号码 显示姓名 显示头像
-
-
构造方法
-
Fu类
package cn.xiaoge.day09.demo07; public class Fu { public Fu() { System.out.println("父类无参构造方法..."); } public Fu(int num) { System.out.println("父类有参构造方法..."); } }
-
Zi类
package cn.xiaoge.day09.demo07; public class Zi extends Fu { public Zi() { // super(); // 在调用父类无参构造方法 super(10); // 在调用父类重载的构造方法 System.out.println("子类构造方法..."); } public void method() { // super(); // 错误写法! 只有子类构造方法, 才能调用父类的构造方法 } }
-
执行路口
package cn.xiaoge.day09.demo07; /* 继承关系中, 父子类构造方法的访问特点: 1. 子类构造方法当中有一个默认隐含的"super()"调用, 所以一定是先调用的父类构造, 后执行的子类构造. 2. 子类构造可以通过super关键字来调用父类重载构造. 3. super的父类构造调用, 必须是子类构造方法的第一个语句. 不能一个子类构造调用多次super构造. 总结: 子类必须调用父类构造方法, 不写则赠送super(); 写了则用写的指定的super调用.super只能有一个, 还必须是第一个. */ public class Demo01Constructor { public static void main(String[] args) { Zi zi = new Zi(); // 先执行父类的构造方法, 在执行子类的构造方法 } } // 运行结果 父类有参构造方法... 子类构造方法...
-
-
super关键字的三种用法
-
Fu类
package cn.xiaoge.day09.demo08; public class Fu { int num = 10; public void method() { System.out.println("父类方法"); } }
-
Zi类
package cn.xiaoge.day09.demo08; /* super关键字有三种用法: 1. 在子类的成员方法中, 访问父类的成员变量. 2. 在子类的成员方法中, 访问父类的成员方法. 3. 在子类的构造方法中, 访问父类的构造方法. */ public class Zi extends Fu { int num = 20; public Zi() { super(); } public void methodZi() { System.out.println(this.num); // 子类的num System.out.println(super.num); // 父类的num } public void method() { super.method(); // 访问父类中的method System.out.println("子类方法"); } }
-
-
this的三种用法
-
Fu类
package cn.xiaoge.day09.demo09; public class Fu { int num = 30; }
-
Zi类
package cn.xiaoge.day09.demo09; /* super关键字用来访问父类内容, 而this关键字用来访问本类内容. 用法也有三种: 1. 在本类的成员方法中, 访问本类的成员变量. 2. 在本类的成员方法中, 访问本类的另一个成员方法. 3. 在本类的构造方法中, 访问本类的另一个构造方法. 在第三种用法当中要注意: A. this(....)调用也必须是构造方法的第一个语句, 唯一一个. B. super和this两种构造调用, 不能同时使用. */ public class Zi extends Fu { int num = 20; public Zi() { // super(); // 这一行不在赠送 this(123); // 本类的无参构造, 调用本类的有参构造. // this(1, 2); // 错误写法 } public Zi(int n) { } public void showNumber() { int num = 10; System.out.println(num); // 局部变量 System.out.println(this.num); // 成员变量 System.out.println(super.num); // 父类中的成员变量 } public void methodA() { System.out.println("AAA"); } public void methodB() { this.methodA(); System.out.println("BBB"); } }
-
-
super和this案例
-
Fu类
package cn.xiaoge.day09.demo10; public class Fu { int num = 10; public void method() { System.out.println("父类方法"); } }
-
Zi类
package cn.xiaoge.day09.demo10; public class Zi extends Fu { int num = 20; @Override public void method() { super.method(); // 调用了父类方法 System.out.println("子类方法"); } public void show() { int num = 30; System.out.println(num); // 30 System.out.println(this.num); // 20 System.out.println(super.num); // 10 } }
-
执行路口
package cn.xiaoge.day09.demo10; public class Demo { public static void main(String[] args) { Zi zi = new Zi(); zi.show(); zi.method(); } } // 运行结果 30 20 10 父类方法 子类方法
-