继承
继承的由来
继承的概念
- 当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类,让多个类吸收公共类中已有特征和行为之后而在多个类型各自内部只需要编写自己独有特征和行为的机制,叫做继承。
- 在Java语言中使用extends(扩展)关键字来表示继承关系。
- 如:
- public class Worker extends Person {} - 表示 Worker 类继承自 Person 类
- 其中 Person 类叫做超类、父类、基类
- 其中 Worker 类叫做派生类、子类、孩子类
- 使用继承提高了代码的复用性,可维护性及扩展性(我在Person类中增添一个属性,在子类中也都有了),是多态的前提条件。
继承的特点
-
子类不能继承父类的构造方法(原因:构造方法名要求与类名相同,子类类名与父类类名不同),私有方法(原因:私有的只能在本类中使用,继承下来也用不了,也就没有意义了),但私有成员变量可以被继承只是不能直接访问。私有方法和私有成员变量能被继承但是不能被直接访问。
-
父类中已有的特征行为,子类能继承下来使用之外,还可以在子类中编写独有的特征和独有的行为,在测试类中依然能够使用。
-
无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加了代码 super() 的效果。按内存的角度来说,可以理解为构造一个子类的对象,先调用父类的构造方法创建一个父类对象,然后在父类的外边追加了一个子类对象,故而可以说子类继承了父类的所有特征行为。
-
super() 和 this() 不能同时出现,因为只有一个第一行
-
使用继承必须满足逻辑关系:子类 is a 父类,也就是不能滥用继承。
-
Java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父类,但一个父类可以有多个子类。C++支持一个孩子有多个爹。
-
Person类
/* 编程实现Person类的封装 */ public class Person { // 1.私有化成员变量,使用private关键字修饰 private String name; private int age; //private boolean gender; // 性别 // 3.在构造方法中调用set方法进行合理值的判断 public Person() { System.out.println("Person()"); } public Person(String name, int age) { System.out.println("Person(String, int)"); setName(name); setAge(age); } // 2.提供公有的get和set方法并在方法体中进行合理值的判断 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if(age > 0 && age < 150) { this.age = age; } else { System.out.println("年龄不合理哦!!!"); } } // 自定义成员方法实现特征的打印 public void show() { System.out.println("我是" + getName() + ",今年" + getAge() + "岁了!"); } // 自定义成员方法描述吃饭的行为 public void eat(String food) { System.out.println(food + "真好吃!"); } // 自定义成员方法描述娱乐的行为 public void play(String game) { System.out.println(game + "真好玩!"); } }
-
Worker类
/* 自定义Worker类继承自Person类 */ public class Worker extends Person { private int salary; public Worker() { super(); // 表示调用父类的无参构造方法,若没有加则编译器自动添加 super() 和 this() 不能同时出现,因为只有一个第一行 System.out.println("Worker()"); } public Worker(String name, int age, int salary) { super(name, age); // 表示调用父类的有参构造方法 System.out.println("Worker(String, int, int)"); //setName(name); //setAge(age); setSalary(salary); } public int getSalary() { return salary; } public void setSalary(int salary) { if(salary >= 2200) { this.salary = salary; } else { System.out.println("薪水不合理哦!!!"); } } // 自定义成员方法描述工作的行为 public void work() { System.out.println("今天的砖头有点烫手..."); } // 自定义show方法覆盖从父类中继承的版本 @Override // 标注/注解,用于说明下面的方法是对父类方法的重写,若没有构成重写则编译报错 public void show() { super.show(); // 表示调用父类的show方法 System.out.println("我的薪水是:" + getSalary()); } }
-
WorkerTest类
/* 编程实现Worker类的测试 */ public class WorkerTest { public static void main(String[] args) { // 1.使用无参方式构造Worker类型的对象并打印特征 Worker w1 = new Worker(); // 当子类重写show方法后,则下面调用的是重写以后的版本,否则调用的是Person类中的show方法 w1.show(); // null 0 System.out.println("----------------------------------"); // 2.使用有参方式构造Worker类型的对象并打印特征 Worker w2 = new Worker("zhangfei", 30, 3000); w2.show(); // zhangfei ... // 调用成员方法测试 w2.eat("豆芽"); w2.play("王者荣耀"); w2.work(); } }
-
Teacher类
/* 编程实现Teacher类继承自Person类 */ public class Teacher extends Person { }
-
TeacherTest类
/* 编程实现Teacher类的测试 */ public class TeacherTest { public static void main(String[] args) { // 1.使用无参方式构造Teacher类型的对象并打印特征 Teacher t1 = new Teacher(); t1.show(); // null 0 我是null,今年0岁了! } }
-
ComputerTeacher类
/* 编程实现ComputerTeacher类继承自Teacher类 */ public class ComputerTeacher extends Teacher { }