面向对象——继承和多态
一. 继承
1.继承:
是一种机制,可以进行代码的重用——基类(超类) 子类(派生类) 子类继承了 父类的除构造函数外的所有属性
2.super关键字:
- super():----->调用基类的构造函数 //必须放在第一行
- super.data------->访问基类的数据成员
- super.func();—>调用基类的成员方法
class Base{
protected int a;
public Base (int a){
fun1();
this.a=a;
}
public void fun1() {
System.out.println("Base.fun1()"+ this.a);
}
}
class Childern extends Base{
private int b;
public Childern(int a,int b) {
super(a);
super.a = 10;
super.fun1();
a=10;
this.b=b;
System.out.println("Childern.init()...");
}
public void fun1() {
System.out.println("Childern.fun1()");
}
public void fun1(int a) {
System.out.println("Childern.fun1(int)");
}
}
3.派生类构造对象的初始化顺序
class Base{
protected int a;
public Base (int a){
fun1();
System.out.println("Base.init()...");
this.a=a;
}
static {
System.out.println("Base.static...");
}
{
System.out.println("Base.instance...");
}
public void fun1(){
System.out.println("Base.fun1()..."+this.a);
}
public static void fun2(){
System.out.println("Base.fun2()...");
}
}
class Childern extends Base{
private int b;
public Childern(int a,int b) {
super(a);
a=10;
this.b=b;
System.out.println("Childern.init()...");
}
static {
System.out.println("Childern.static...");
}
{
System.out.println("Childern.instance...");
}
public void fun1(){
System.out.println("Childern.fun1()...");
}
public void fun1(int a){
System.out.println("Childern.fun1(int)...");
}
public static void fun2(){
System.out.println("Childern.fun2()...");
}
}
public class Test1031_2 {
public static void main(String[] args) {
Base base =new Childern(1,2);
}
}
打印结果为:
Base.static...
Childern.static...
Base.instance...
Childern.fun1()...
Base.init()...
Childern.instance...
Childern.init()...
可以看出派生类构造对象的初始化顺序:
- 基类的静态块初始化,
- 派生类的静态块初始化
- 基类的实例块初始化
- 基类的构造函数
- 派生类的实例块初始化
- 派生类的构造函数
4.基类的数据成员在派生类当中的访问权限
同包子类 | 同包非子类 | 不同包子类 | 不同包非子类 | |
---|---|---|---|---|
public | 可以 | 可以 | 可以 | 可以 |
private | 不可以 | 不可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 不可以 | 不可以 |
默认权限 | 可以 | 可以 | 不可以 | 不可以 |
5.基类和派生类之间的相互赋值
派生类的值可以赋值给基类;
但是基类的值不能赋值给派生类
例如:上面那段代码 然后主函数改成:
public static void main1(String[] args) {
Base base = new Base(1);
Childern childern = new Childern(1,2);
base = childern;//这句就是正确的
childern = base;//这句就是错误的,error
}
6.重载:overlode; 函数名相同,参数列表不相同,与函数返回值无关 并不一定在同一个类当中;继承关系上也可以构成重载;
重写/覆盖:overwrite;函数名相同,参数列表相同,函数返回值相同
三.多态:
基类引用了派生类对象,并且基类和派生类有同名的覆盖方法
动多态:发生在运行的时候
静多态:发生在编译的时候
方法表是在编译的时候生成的,
一般的对象放在堆里 class对象例外放在方法区
方法表和类型一一对应
public static void main2(String[] args) {
Base base=new Base(1);
Childern childern=new Childern(1,2);
base=childern;
}
public static void main3(String[] args) {
Base base=new Base(1);
base.fun1();
System.out.println("===============");
Childern childern=new Childern(1,2);
childern.fun1();
}
public static void main4(String[] args) {
Base base=new Childern(1,2);
base.fun1();//动多态 运行的时候
Base.fun2();//静多态 编译的时候
}