定义
在现有类的基础上重新构造一个新类,现有的类叫父类或者超类, 新的类叫子类或者派生类或者扩展类 从父类的角度叫派生或者扩展,从子类的角度叫继承
子类继承父类,子类可以继承父类中私有成员与构造函数以外的一切成员(因为父类的构造函数无法预知子类新增的属性及方法)
java只支持单一继承,不支持多重继承(危害:同一方法继承了不同的实现)。
多重继承的钻石问题
有两个类B和C继承自A。假设B和C都继承了A的方法并且进行了覆盖,编写了自己的实现。假设D通过多重继承了B和C,那么D应该继承B和C的重载方法,那么它应该继承哪个的呢?是B的还是C的呢?(BC都是D的父类)
继承的时候的内存分配:先是在堆内存中划分一块子类对象的内存,在子类对象的内存中对父类的成员的属性进行初始化,在将子类的属性等进行初始化,在将子类实例对象赋给引用变量。
Object类是所有类的父类
子类继承父类,在构造子类对象时一定会构造它所继承的父类的对象并调用父类的构造函数完成父类属性的初始化(先构造父类对象,再构造子类对象)
构造子类对象时,会采用内存覆盖的方式管理它所继承的父类对象
使用特征:
1.子类继承父类,子类可以看成是父类类型的,意思是指用父类类型的引用变量可以直接指向或者接收任何子类的实例对象
2.当用父类类型的引用变量指向任何子类的实例对象时,该子类的实例对象就变成父类类型的了,编译器通过父类类型的引用变量无法调用子类新增的属性和方法
方法的覆盖:
※:父类不满足子类要求的情况下,子类可以:
① 新增属性和方法
② 把从父类中继承过来的方法进行修改,即方法覆盖:
方法覆盖:在子类中对从父类中继承过来的方法进行修改(只能修改方法体),即子类覆盖方法与父类被覆盖方法具有相同的方法名、参数列表以及返回值类型
子类覆盖方法不能使用比父类被覆盖方法更严格的访问权限
。覆盖Object类的toString()方法:
。System. out. println(参数):
。如果参数是基本数据类型,会先调用String的valueOf()方法将其转换为字符串后写到屏幕上
。如果参数是引用数据类型,会调用该对象的toString()方法将其转换成字符串后写到屏幕上
。覆盖Object类的toString()方法:仅限于保存数据的类中覆盖该方法
。Object类的toString()方法返回的还是对象的地址值而非对象的属性值,表现形式是:getClass(). getName() +@+Integer. toHexString(hashCode())
※:vo(value-obkect):以对象的形式保存数据
数据的比较:
。对于栈中的数据,用“==”比较:
。对于基本数据类型的数据,比较内存中的数据值
。对于引用数据类型数据,比较栈中的两个引用变量是否指向堆中的同一个对象
。对于堆中的对象,用equals()比较
。Equals():比较对象的属性值
。覆盖Object类的equals()
。 Object类的eqalus()是比较两个引用变量是否指向同一个对象,而非比较对象的属性值
※:子类对父类的方法进行覆盖时,在覆盖方法中应极可能多的调用父类被覆盖方法的功能
子类对父类的调用
1. 显式调用:
。super: 在子类中表示子类所继承的父类的对象。
在子类中调用父类中与子类中重名的属性与方法时
。super(参数):在子类的构造函数中调用父类的构造函数完成子类属性的初始化。
2. 隐含调用:在构造子类对象时,系统会采用内存覆盖的方式构造它所继承的父类的对象并调用父类的构造函数完成父类属性的初始化,因此,在子类的构造函数中如果没有明确指明调用父类的构造函数,系统默认调用父类无参的构造函数。
※:子类继承父类,父类应该初始化自己的成员而不应由子类来完成
方法的重载(overload):
在同一个类中多个方法具有相同的方法名,不同的参数列表,返回值可以相同,也可以不同,相互之间可以直接调用。