java入门(十九) | OOP(六)之继承 — OCP原则
继承 — OCP原则
1.1 概念
- 继承是面向对象最显著的一个特性
- 继承是从已有的类中派生出来新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力
- Java继承使用已存在的类的定义作为基类/父类/超类,新类的定义可以增加新的数据或新的功能,也可以用父类的功能
- 不能选择性地继承父类(超类,基类)
- 继承使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用
1.2 特点
- 使用extends关键字
- 相当于子类把父类的功能复制了一份
- java只支持单继承
- 不能继承父类的私有成员
- 继承可以传递(爷爷,儿子,孙子的关系)
- 继承多用于继承的修改,子类可以拥有父类的功能的同时,进行功能扩展
- 依赖性和耦合性都很强
1.3 入门案例
package cn.qile.extendsdemo;
//继承的入门案例
public class Test1_Extends {
public static void main(String[] args) {
//创建子类Dog对象测试
Dog d = new Dog();
d.eat();//2.1、可以使用父类的所有功能
System.out.println(d.getSum());
//创建DaHuang类对象测试
DaHuang huang = new DaHuang();
huang.eat();//4.1、继承可以传递
//5、父类的私有成员,子类无法继承
// System.out.println(huang.sum);
}
}
//创建父类
class Animal{
public void eat() {
System.out.println("吃啥都行");
}
}
//创建子类
//1、extends关键字用来表示继承关系
//3、java中只支持单继承 , 是 is a 的关系 , 子类要强制继承父类,才能用父类的功能
class Dog extends Animal{ //耦合性强--两者的关系就是强制依赖
//2、子类继承父类就能无偿使用,因为相当于把父类的功能复制了一份
private int sum = 10;
public int getSum() {
return sum;
}
}
//创建孙子类
class DaHuang extends Dog {
//4、继承可以传递,Animal的功能也能用
}
2. super关键字
- 通过super关键字可以使用父类的内容
- super代表父类的一个引用对象
- 如果在构造方法中使用,必须是第一条语句
3. 方法重写Override
- 继承后,子类就拥有了父类的功能
- 在子类中,可以添加子类特有的功能也可以修改父类原有功能
- 子类中方法的声明与父类完全一样是,会发生覆盖/复写/重写操作
- 方法的声明:包括方法的返回值,方法名和参数列表,完全一致。
注意:
- 父类中的私有方法不能被重写
- 子类重写父类方法时,修饰符要>=父类修饰符
- 父类中的构造方法不能被子类继承
4. 继承中的用法
4.1 成员变量的使用
package cn.qile.extendsdemo;
public class Test2_UserExtends {
public static void main(String[] args) {
// 创建父类对象测试
Baba b = new Baba();
b.eat();
}
}
//创建爷爷类
class Yeye{
int count = 30;
int sum = 50;
}
//创建父类
class Baba extends Yeye{
int sum = 20;
public void eat() {
int sum = 10;
System.out.println(sum);//10
System.out.println(this.sum);//20,this调用成员变量
System.out.println(count);//30
System.out.println(super.sum);//50,通过super关键字使用父类的资源
}
}
总结:继承中,如果要使用父类的成员变量 — 通过super调用父类成员变量
4.2成员方法的使用
package cn.qile.extendsdemo;
public class Test3_UserExtends {
public static void main(String[] args) {
//创建父类对象测试
Father f = new Father();
f.eat();//爸爸在吃肉
f.study();//爸爸在赚钱
//创建子类对象测试
Son s = new Son();
//4、如果没有发生重写现象,使用的就是继承过来的父类的功能。
//但是,如果发生了重写现象,从此使用的都是重写后的效果。
s.eat();//5、从爸爸在吃肉变成了儿子在喝汤
s.study();//爸爸在赚钱? -- 儿子在学Java
s.play();//正在吃鸡
}
}
//创建父类
class Father{
public void eat() {
System.out.println("爸爸在吃肉");
}
public void study() {
System.out.println("爸爸在赚钱");
}
}
//创建子类
class Son extends Father{
//子类特有功能
public void play() {
System.out.println("正在吃鸡");
}
//1、如果子类想要修改父类的功能 -- 方法的重写Override
//2、重写:子类的方法声明和父类一模一样(返回值 方法名 参数列表)
//3、重写中,父类原本的功能并没有影响,改的是子类自己的功能--super.eat()
public void eat() {
System.out.println("儿子在喝汤");
}
//重写父类的study()
public void study() {
System.out.println("儿子在学Java");
}
}
总结:
- 如果只是继承,子类用的就是父类的功能
- 如果继承后,发生重写,子类用的就是重写后的功能
- 重写的意义:是在不修改远吗的前提下,进行功能的扩展,就算是发生了重写后,父类本身功能并没改
4.3 构造方法的使用
- 子类创建对象是,默认会去访问父类的无参构造方法
- 在子类构造方法的第一行,都会有一条默认的语句:super() / this()
- 父类没有无参构造时,可以用super调用父类的其他构造
package cn.qile.extendsdemo;
//继承中构造方法的使用
public class Test4_UserExtends {
public static void main(String[] args) {
//创建子类对象测试
Zi z= new Zi();
}
}
//创建父类
class Fu{
/*当父类没有无参构造时
* public Fu() { System.out.println("父类构造方法"); }
*/
public Fu(String n) {
System.out.println("父类构造"+n);
}
}
//创建子类
class Zi extends Fu{
public Zi() {
//1、第一行隐藏着super(),会自动调用了父类的无参构造
// super();
//2、当父类没有无参构造时,子类通过super调用父类的含参构造
super("rose");
System.out.println("子类构造方法");
}
}
5. this和super的区别
- this代表本类对象的引用,super代表父类对象的引用。
- this用于区分局部变量和成员变量
- super用于区分本类变量和父类变量
- this.成员变量 this.成员方法() this( [参数] )代表调用本类构造方法
- super.成员变量 super.成员方法() super( [参数] ),代表调用父类构造方法
- this和super不可以同时出现在同一个构造方法里,因为他们两个只要出现都得放在第一行。