1/* 继承: 向上抽取共性,把相同的内容定义在父类中 public class 子类 extends 父类 { //成员变量 +成员方法 +构造方法 } 2.子类可以使用父类中除了private修饰的和构造方法以外的内容 */ public class Demo01Extends { public static void main(String[] args) { //创建子类Teacher类的对象 Teacher t = new Teacher(); //给成员变量赋值 t.name = "响哥"; t.salary/birthday = 66666; t.show(); // } }
2
/* 继承中的成员变量访问特点 1.不重名的成员变量 (1)子类自己有: 优先使用子类自己的 (2)子类没有: 找父类 (3)注意: 子类可以找父类,但是父类不能找子类 2.重名的成员变量 (1)方法内部,直接写变量名 从方法内部开始向上找 方法内部有: 直接使用 方法内部没有: 向上找,本类的成员位置 本类的成员位置有: 直接使用 本类的成员位置没有: 向上找,父类的成员位置 (2)方法内部,直接写this.变量名 从本类的成员位置开始向上找 本类的成员位置有: 直接使用 本类的成员位置没有: 向上找,父类的成员位置 (3)方法内部,直接写super.变量名 从父类成员位置开始向上找 父类的成员位置有: 直接使用 父类的成员位置没有: 继续向上找 (4)总结:就近原则 this.变量名: 代表当前类的成员变量 this.num
super.变量名: 父类的成员变量 super.num
*/
继承中成员方法的访问特点 1.子类自己有: 优先使用子类自己的 2.子类没有: 向上找父类 3.重名的方法(方法重写): 优先使用子类自己的
方法重写 1.概念: 子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同), 会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。 必要条件:方法名和参数列表必须相同 可选条件:返回值类型可以不一致(后面讲) 2.最简单的方法重写形式: 子类方法声明(定义方法的第一行)和父类方法声明一模一样 3.@Override注解:用来检测子类方法,是否是对父类方法的覆盖重写 4.与方法重载区分开: 方法重载作用: 是节约命名空间 方法重载要求: 方法名称相同,参数列表不同(类型不同,数量不同,多个不同类型的顺序不同) 5.方法重写快捷键: ctrl + o --> 选择要重写的方法 --> ok
直接调用父类的成员方法: super.成员方法名称(参数列表...)
//@Override public void show(int num) { System.out.println("Zi03...show...num..." + num); } @Override //不报错: 是对父类方法的重写,因为方法名称相同,参数列表也相同 public void show() { System.out.println("Zi03...show..."); } //在Zi03类中出现了两个show方法,不报错 //原因: 名称相同,参数列表不同,构成了重载关系
public class NewPhone extends OldPhone { @Override public void show() { //System.out.println("110来电..."); //显示电话号码,其实父类的show方法已经实现该功能, //子类不用自己重新实现了,直接调用父类的功能 super.show(); System.out.println("显示归属地: 东莞..."); System.out.println("显示头像: 🃏"); } }
//满参构造 public Zi05(int num) { /* 如果没有自己写super调用父类构造, 隐藏提供super()调用父类的空参构造 */ //但是建议: 子空参 调用 父类空参 //但是建议: 子满参 调用 父类满参 super(num); System.out.println("子满参..."); //super(num);//错误: 调用父类构造必须写在第一行 }
//创建子类对象: 空参构造 Zi05 zi = new Zi05(); //创建子类对象: 满参构造 Zi05 zi2 = new Zi05(100);
/* 继承中构造方法的访问特点 1.构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的 2.子类继承父类,是为了使用父类的内容, 所以子类创建对象调用构造方法时, 必须先调用父类的构造方法, 完成父类成员的初始化动作, 子类才可以使用父类的成员, super()表示调用父类的空参构造 3.子类的构造方法中如果没有手动给出super调用父类构造, 编译器默认提供一个super()调用父类的空参构造 4.super调用父类构造,只能写在第一句 5.构造方法可以重载,所以: super(...):调用父类带参数的构造方法 //创建子类对象: 空参构造 Zi05 zi = new Zi05(); //创建子类对象: 满参构造 Zi05 zi2 = new Zi05(100); super的用法: 1.super.成员变量名: 代表父类的成员变量 2.super.成员方法(参数列表...): 代表调用父类的成员方法 3.super(参数列表...): 代表调用父类的构造方法 this的用法: 1.this.成员变量名: 代表本类自己的成员变量(自己没有找父类) 2.this.成员方法(参数列表...): 代表本类自己的成员方法(自己没有找父类) 3.this(参数列表...): 代表调用本类自己的其它构造方法 ---后面讲 */
public class Fu05 { private int num; //空参构造 public Fu05(){ System.out.println("父空参..."); } //满参构造 public Fu05(int num) { System.out.println("父满参..."); this.num = num; } //get和set方法 public void setNum(int num) { this.num = num;// super(num); public int getNum() { return num; } }
/* 如果没有自己写super调用父类构造, 隐藏提供super()调用父类的空参构造 */ //但是建议: 子空参 调用 父类空参 //但是建议: 子满参 调用 父类满参
/* 定义父类员工Employee类 1.所有成员变量private修饰 2.提供空参/满参构造方法 3.提供get/set方法 4 //特有方法: */ //创建子类Teacher类的对象: 满参构造 // Teacher t = // new Teacher("响哥",18,66666,33333); // // //调用成员方法 // t.show(); // t.teaching(); // System.out.println("-----------"); // // //创建子类Manager类的对象: 空参构造 // Manager m = new Manager(); // // //给成员变量赋值 // m.setName("玲姐"); // m.setAge(16); // m.setSalary(88888); public class Employee { // private成员变量 //成员方法: 展示信息 //2.提供空参构造方法 //2.提供空参构造方法 //3.提供get/set方法 }
/* 类的继承特点 1.Java只支持单继承,不支持多继承。 //Java中的类可以多层继承爷父子 2.Java支持多层继承(继承体系)。 3.所有的类都直接或者间接继承了Object类,Object类是所有类的最终父类。 */ //错误: 一个类只能直接继承一个父类
public abstract class Animal { //成员变量 //空参构造 //满参构造 //展示信息的方法 //抽象方法: 吃 //抽象方法: 睡 //get和set方法 }
public abstract class Animal { //抽象方法: 吃 public abstract void eat(); //抽象方法: 睡 public abstract void sleep(); }
/* 抽象父类和之前普通类的定义的区别? 1.不能直接创建对象 2.内部可以定义抽象方法 */
/* 抽象: 2.抽象类中抽象方法存在的意义:强制要求子类必须具备的能力 3.抽象类的定义格式: public abstract class 类名 { ... } 4.抽象方法的定义格式:
//错误: 不能直接创建抽象类的对象 //Animal a = new Animal(); //创建Cat类的对象 Cat cat = new Cat(); //子类对象调用成员方法 cat.eat(); cat.sleep();
修饰符 abstract 返回值类型 方法名称(参数列表...); 注意: (1)和以前定义方法一样,但是去掉{},添加abstract关键字 (2)返回值类型和参数列表根据需求确定 (3)含有抽象方法的类,必须定义为抽象类,但是抽象类中不一定含有抽象方法 5.抽象类的使用 (1)不能直接创建抽象类的对象 (2)定义子类,继承抽象父类 (3)子类中覆盖重写抽象父类中的所有抽象方法 去掉abstract关键字,添加{} 快捷键: ctrl + i (4)创建子类对象 (5)子类对象调用方法 */
//-----------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
/* 抽象类的注意事项: (3)含有抽象方法的类,必须定义为抽象类,但是抽象类中不一定含有抽象方法 4.抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类 3.抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类 看: MyAbstractClass 1.抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象 2.抽象类中,必须有构造方法,是供子类创建对象时,初始化父类成员使用的
//-----------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
*/
//错误: 不能直接创建抽象类的对象 //Animal a = new Animal(); //创建Cat类的对象: 空参构造 Cat cat = new Cat(); //调用set方法给成员变量赋值 cat.setName("小花"); cat.setWeight(10);
问题: Animal中有两个抽象方法eat和sleep,但是对应当前子类而言, 只覆盖重写了一个抽象方法eat,相当于子类自己有个抽象方法sleep 当前子类必须定义为抽象类 public abstract void sleep();