如果子类重写了父类的方法,子类对象又要使用父类的方法怎么办
继承
今日内容
所有的类都直接或者简洁的集成到了Object
Object:祖宗类
概述
要定义的类属于已有类的一种时,可以将该类定义为已有类的子类
当多个类有共性内容,可以将共性内容向上抽取,到一个新的父类
这种关系就叫做继承
继承的格式
通过extends关键字,可以声明一个类继承另外一个父类,格式如下
class 父类 {...} class 子类 extends 父类 {...}
这样做的好处:
●提高了代码复用性
●类与类之间产生了关系,是多态的前提
匿名对象
匿名对象是指创建对象时,只有创建对象的语句,而没有把对象地址值赋值给某个变量
public class Person{
public void eat(){
System.out.println();
}
}
public class Test{
public static void main (String[]args){
//创建一个普通对象
Person p = new Person();
//创建一个匿名对象
new Person();
}
}
匿名对象的特点:
● 创建匿名对象直接使用,没有变量名.
new Person().eat() //直接调用了eat方法
● 匿名对象在没有指定其引用变量时,只能使用一次
new Person().eat();创建一个匿名对象,调用eat方法
new Person().eat();重新创建了一个匿名对象,再次调用
● 匿名对象可以作为方法的参数和返回值使用
public class Test{
public static void main (String []args){
//调用method方法
Person p = new Person();
method(p);
//匿名对象作为方法接收的参数
Demo.method(new Person());
}
public static void method (Person p){
p.eat()
}
public static Person getPerson(){
//匿名对象作为方法的返回值
return new Person();
}
}
java继承后成员变量的特点:
如果子类父类中出现不重名的成员变量
这时访问时没有影响的.
如果子父类成员中出现了相同的成员变量
那么创建该子类对象的时候,用的是子类的成员变量
就近原则 :自己本类有的,就不去父类找了
为了能在子类中创建父类对象,所以使用super关键字(下详)
java继承后成员方法的特点:
如果子父类中出现不重名的成员方法
这时调用是没有影响的, 根据优先原则,在子类先查找有无对应方法,若没有再去父类找
如果成员方法重名---方法重写(Override) (下详)
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写(Override)
● 子类中出现与父类一模一样的方法时(返回值类型 方法名 参数列表),会出现覆盖效果 声明不变,重新实现
代码如下:
class fu {
public void show(){
System.out.println("fu show");
}
}
class zi extends fu {
//子类重写show方法
public void show(){
super.show(); // fu show 这里重写时,用到super.父类成员方法,表示调用父类的成员方法.
System.out.println("zi show");
}
}
//测试类
public class extendstest{
public static void main (String [] args){
zi z = new zi ();
//zi类有show方法,只执行重写后的show方法.
z.show(); //zi show
注意事项
- 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
- 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
- 私有方法不能被重写(父类私有成员子类是不能继承的)
java继承后构造方法的特点
需要先搞清楚的是子父类谁先完成初始化的问题
总结: 一定是父类先进行初始化,子类随后进行初始化
因为子类在创建对象的时候可能会用到父类的成员,如果父类没有完成初始化,子类将使用不到这些成员
问题:子类在创建对象之前,是怎么样完成父类初始化的呢
在子类的所有构造方法中,都默认隐藏了一个语句,super();
问题:为什么要隐藏一个super()来调用父类的构造方法呢?
答:因为初始化一个对象,就要走该对象的构造方法.
回忆: - 构造方法的名字与类名是一致的,所以子类是无法继承父类构造方法的 - 构造方法的作用是初始化成员变量的,所以子类的初始化过程中,必须先 执行父类的初始化动作. - 子类的构造方法中默认有一个super();表示调用父类的构造方法,父类 成员变量初始化后,才可以给子类使用
代码如下:
class Fu {
private int n;
Fu(){
System.out.println("Fu()");
}
}
class Zi extends Fu {
Zi(){
// super(),调用父类构造方法
super();//不写也有,默认的
System.out.println("Zi()");
}
}
public class ExtendsDemo07{
public static void main (String args[]){
Zi zi = new Zi();
}
}
输出结果:
Fu()
Zi()
子类的每个构造方法中均有默认的super(),调用父类的空参构造.
手动调用父类构造会覆盖默认的super()
super()和this()都必须在构造方法的第一行所以不能同时出现
super关键字的概述和使用
super关键字代表什么? this和super的区别又是什么?
this :代表当前对象的引用,谁来调用我,我就代表谁 -->this代表本类对象的引用
Super:代表父类的储存空间标识(可以理解为父类的引用)
代表父类空间的引用 --> 简单记:super可以调用父类的相关成员
成员变量
this.子类成员变量名 :调用本类的成员变量. this也可以调用父类的成员变量,但是存在前提(子父类中没有出现重名的成员变量) 原因是,父类中的成员被子类继承下来了,既然子类继承下来了,就相当于子类自己有份,this也相当于调用自己的,是没有问题的
super.父类成员变量名 :调用父类的成员变量.
成员方法
this.成员方法 :调用本类的成员方法,也可以调用父类的成员方法,前提是子父类中没有重名的方法 super.成员方法 :调用父类的成员方法
构造方法
(不是this. super. 了 而是this(),super(),super()用的比较多)
this() : 只能调用本类构造方法
super() : 只能调用父类构造方法
Override方法重写
什么情况下,要进行方法的重写?
overlode和override的区别? overlode:方法重载
在同一个类中 方法名相同,参数列表不同(类型不同,个数不同,顺序不同),与返回值无关
override:方法重写,也叫覆盖/覆写
在子父类中,出现了方法声明一模一样的方法,就称为方法重写
方法名一样,参数列表也一样
什么情况下要进行方法的重写?
当子类需要父类的功能,而子类方法的功能主体又有自己的特有实现方式,这样做既沿袭了父类的功能, 又定义了子类特有的内容
也就是说,当子类觉得父类的逻辑不好,或者说过于老旧,就可以对父类的方法进行重写
重写:强化父类功能
注解 @Override:用于检测当前的方法是否是重写的方法,放在方法上面,如果下面的方法不是重写的,会报错
方法重写的注意事项
- 子类不能重写父类私有的方法,因为子类中看不到父类私有(private)的方法
- 子类重写父类方法的时候,访问权限必须大于等于父类,最好就一致
- 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型.
- 如果父类没有抛出异常,子类重写父类该方法时也不能抛出异常,此时子类产生该异常,只能捕获处理,不能声明抛出
权限修饰符: private 最小的 default(默认,什么都不写) protected(受保护的) public(公共的)
继承的特点
- java只支持单继承,不支持多继承(有一个亲爹(还可能有一个干爹接口))
- java支持多层继承(继承体系)
- 所有的类都直接或者间接继承了Object类