> 文章列表 > 继承和多态(1)

继承和多态(1)

继承和多态(1)

        什么是继承?继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了 由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。被继承的是父类,也叫超类,基类,继承的是子类,派生类。

class Person{//父类public String name;public int age;
}
class Student extends Person{//子类public int grades;
}
Java中如果要表示类之间的继承关系,需要借助extends关键字。
注意:
1. 子类会将父类中的成员变量或者成员方法继承到子类中了
2. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了
3.子类与父类之间必须要有某种联系,不能因为父类的成员变量中有子类所需要的就继承,如:
class Animal{public String name;public int age;
}
class Student extends Animal{public int grades;
}

虽然语法可以通过,但逻辑上不行,怎么可以将风马牛不相及的东西放在一起呢,这会增加代码的阅读难度。

        如果子类要访问父类的成员,要如何访问呢?若要访问的父类成员,在子类中没有相同的,则与访问子类成员的方法一样,可以通过对象名来使用,但不能通过this来访问父类成员,若子类中有相同的,这要通过关键字super访问。

class Student extends Person{//子类public String name;public int grades;public void eat(){System.out.println(super.name + "年龄为" + super.age + "正在吃饭");}
}

注意:

在子类方法中 或者 通过子类对象访问成员时
如果访问的成员变量子类中有,优先访问自己的成员变量。
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找
通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用 方法适传递的参数选择合适的方法访问,如果没有则报错;
super关键字
1. 只能在非静态方法中使用
2. 在子类方法中,访问父类的成员变量和方法
        子类的构造方法
在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子,肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整
注意:
1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构 造方法
2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的 父类构造方法调用,否则编译失败。
3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现
class Person{//父类public String name;public int age;
}
class Student extends Person{//子类public int grades;public Student(int grades){this.super();//this和super同时出现,报错super();this.grades = grades;}
}

        那么子类和父类的的初始化顺序是什么呢?谁先初始化呢?如果里面包含了静态代码块和实例代码块呢?

1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
class Person{public String name;public int age;static {System.out.println("父类静态代码块");}{System.out.println("父类实例代码块");}public Person(){System.out.println("父类构造方法");}}
class Student extends Person{static {System.out.println("子类静态代码块");}{System.out.println("子类实例代码块");}public Student(){System.out.println("子类构造方法");}
}

打印结果为:

父类静态代码块
子类静态代码块
父类实例代码块
父类构造方法
子类实例代码块
子类构造方法

继承就先到此结束了。