2021-01-20

面向对象编程
一、继承
目的:代码重用,类的重用
概念:父类(基类,超类)子类(派生类)
关键字: extends (扩展)
1.Animal这样被继承的类我们称之为父类,基类或超类,对于像Cat和Bird这样的类,我们称之为子类,派生类
2.语法规则
(1)基本语法
Class 子类extends 父类{
}
使用extends指定父类
JAVA中一个子类只能继承一个父类(C++/Python支持多继承)
子类会继承父类的所有public的字段和方法
对于父类的private的字段和方法,子类中是无法访问的
子类的实例中也包含父类的实例,可以使用super关键字得到父类实例的引用
注意:
当Cat类或者Bird类继承了Animal类之后,就会把父类的name继承过来,所以在子类当中,可以通过this关键字访问到name属性。
子类继承父类后,子类需要先构造父类。所以在子类的构造函数当中,要通过super()显示调用父类的构造方法。
3.Java叫做“单继承"
一个类只能有一个父类,但是这个父类还可以继承自其它的类
子类 => 父类 => 爷爷类这种是允许的,但是一对多(例如猫头鹰即是鸟又是猫)这是不允许的
Java中不支持这种多继承,其它语言中有的是支持的.
子类会继承父类所有的属性和方法,无论是public还是private,只不过private修饰的成员在子类中无法访问.
Private只是在类的内部才能够访问到.哪怕是自己的子类也不行
4.子类的实例中也包含着父类的实例
当我们去new一个Cat实例的时候,就会先创建一个Animal实例(在Cat 内部的),即New Cat中包括父类的实例(使用super关键字就能过获取到父类实例的引用)和子类的实例((this)cat.name才能访问,正因为name这个属性在子类实例中存在才能访问)
每个子类的实例里面都包含一个父类的实例,有几个子类的实例就对应到几个父类的实例
5.
每个类都有构造方法,如果你不显式的创建构造方法,那么编译器就会给这个类自动生成一个没有参数的构造方法,当父类里面没有写构造方法的时候,就被自动生成了没参数版本的构造方法,此时如果直接new子类实例,就会调用到刚才父类这个没参数版本的构造方法,当父类里有构造方法的时候,并且这个构造方法带有参数的时候,编译器就不再自动生成无参数版本的构造方法了,此时再创建子类实例,就需要显式的调用父类的构造方法,并且进行传参,否则创建不出来父类的实例,就会编译出错。
可以理解成如果父类没有自定义的构造方法,子类也有没父类的构造方法,系统会给子类默认生成一个如下的构造方法

public类名(){
    
    
Super();
}

显式:必须要明确的写出来

 public Cat() {
    
                            
super( name:“小黑");                 
}       

隐式:不写也行

 public Cat(){
    
    
   }      

修改这个问题办法也很简单,只要在子类的构造方法中,显式调用父类的构造方法即可。(使用super关键字)
创建子类实例的时候,自动创建父类实例,这个过程是必要的,尤其是如果父类有多个构造方法的时候,更需要明确告诉编译器使用哪种方式构造父类实例了,使用super显式调用构造方法
构造子类实例的时候,会在子类实例的内部自动构造一个父类的实例(子类实例中包含了父类的实例,父类的实例里就包含了父类的属性)
6.
如果父类有多种构造方法,这个时候构造子类的时候就需要显式的决定使用哪个构造方法,另一方面,如果父类里头只有一个没参数版本的构造方法, 此时子类就可以省略父类的构造方法的调用(不写构造方法,就相当于生成数的空的构造方法),再另一方面,如果父类里头没有显式的定义任何构造方法,此时相当于编译器自动给父类生成了没有参数的构造方法,子类仍然不需要显式调用(同上)
Static不能修饰构造方法,它修饰方法变成了类方法
父类只有一个带参数的构造方法,子类必须显式调用。(没有不带参数的构造方法)

public Animal(String name){
    
    
this.name = name;
}

7 .name这个属性是从父类这里继承过来的,既可以使用this.name的方式获取,也可以使用super.name的方式获取﹒获取到的是同一个name

System.out.println(this.name +“正在跳");
System.out.println( super.name+“正在跳");

如果有一个另外的属性,只是在子类中存在,那么此时就不能通过super来访问了,就只能通过this访问
在这里插入图片描述

8.子类继承父类后,子类需要先构造父类
创建子类实例的时候,先构造父类对象(执行父类构造方法的逻辑)再构造子类对象(强制的要求)(再执行子类构造方法的逻辑)
如果是显式调用父类的构造方法,那么必须把父类的构造方法放到第一行代码去执行,不能放到下面。
9.访问权限控制
private:只能在类内部访问 权限要求最高
default(啥都不写,默认的):包级权限,可以被同包的其他类访问
protected:可以被子类访问. 也可以被同包的其他类访问到
protected在被同包的类访问的基础上,还能被其他包的子类访问
public: 可以在类外部访问 权限要求最低
(能被访问的范围越小就认为越高)
后面的有些编程语言,Python, Go, Dart…里面只有public / private之分.
10.
可以使用static来修饰一个内部类,表示这是静态内部类,和继承没啥关系
类前面的public 和继承也没啥关系
给这个类前面加上public表示这个类可以被其他包使用,如果不加public表示这个类只能在包内使用,不能加protected和private
能用private的就尽量用private
继承的层数不要太多,一般原则上不希望继承超过3层,如果类的体系变的非常复杂,维护成本就是很高的(使用final显式的禁止继承.防止继承被滥用)
11.final关键字
final 关键字也能修饰类, 此时表示被修饰的类就不能被继承,final 关键字的功能是 限制 类被继承
在这里插入图片描述

二、组合
1.和继承类似,组合也是一种表达类之间的关系的方式,也是能够达到代码重用的效果
2.组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段
3.组合表示 has - a 语义
(拥有xxx,包含xxx) 实际开发中绝大部分的情况都是使用组合
4.继承表示 is - a 语义
(是xxx)

猜你喜欢

转载自blog.csdn.net/WSXHN/article/details/112893055