Android关于继承-【属性】和【方法】-多态的探究(我会煮很多栗子的)

前言:写代码要抽象,抽象-具体就牵涉到继承,在做项目的过程中,如果许多子类都拥有相同的实现的方法和属性,就会把它们提取到一个共同的父类中,可是在使用过程中,我产生了一些疑惑,比如:子类如果重写了父类的属性是怎么样的结果?于是有了下面的一系列例子来探究。

栗子1

父类和子类都拥有相同的属性,用多态的方式声明,定义为子类,属性属于谁?

//Father.java
public class Father {
    public String name = "Father";
}

//Son.java
public class Son extends Father {
    public String name = "Son"; //子类重写了属性
}

//Main.java
public static void main(String[] args) {
    //test 1
    Father son = new Son(); //多态
    System.out.println("son --- " + son.name);

    //test 2
    Son son1 = new Son();
    System.out.println("son1 --- " + son1.name);
}

输出结果:

son --- Father
son1 --- Son

【栗子1说明】属性不具备多态性,谁定义的实例,属性就是属于谁。


栗子2

父类和子类拥有相同的属性,父类有个获得该属性的方法,子类调用会得到谁的属性?

//Father.java
public class Father {
    public String name = "Father";

    //父类加了一个方法
    public void printName() {
        System.out.println("Father: ---" + name);
    }
}

//Son.java
public class Son extends Father {
    public String name = "Son"; //子类只重写了属性
}

//Main.java
public static void main(String[] args) {
    //test 1
    Father son = new Son();
    son.printName(); //调用父类方法打印

    //test 2
    Son son1 = new Son();
    son1.printName(); //调用父类方法打印
}

输出结果:

Father: --- Father
Father: --- Father

【栗子2说明】子类默认继承父类的方法,如果不重写该方法,里面使用的是变量是父类的变量

【扩展说明】这就是好比为什么我们写一个BaseView的时候,在onCreate()里面用的不是setContentView(R.layout.mainXXX),而是setContentView(getContentViewRes()),然后由子类去重写int getContentViewRes()方法即可。


栗子3

在栗子2的基础上,子类重写父类的方法

//Father.java
public class Father {
    public String name = "Father";

    public void printName() {
        System.out.println("Father: --- " + name);
    }
}

//Son.java
public class Son extends Father {
    public String name = "Son";
    //子类重写了printName方法
    public void printName() {
        System.out.println("Son: --- " + name);
    }
}

//Main.java
public static void main(String[] args) {
    //test 1
    Father son = new Son();
    System.out.println("--- son name is " + son.name);
    son.printName(); //调用子类方法打印
    System.out.println("--- son name is " + son.name);

    //test 2
    Son son1 = new Son();
    System.out.println("--- son1 name is " + son1.name);
    son1.printName(); //调用子类方法打印
    System.out.println("--- son1 name is " + son1.name);
}

输出结果:

--- son name is Father
Son: --- Son
--- son name is Father

--- son1 name is Son
Son: --- Son
--- son1 name is Son

【栗子3说明】子类继承父类的方法,如果重写该方法,里面使用的是变量是自己的变量,即使是用多态定义的。


2、3的例子,我理解成,在的方法中,就会调用的属性。


栗子4

父类和子类拥有相同的属性,在父类方法中,有一个方法是改变属性的,那么子类调用是否会改变自己的属性?

//Father.java
public class Father {
    public String name = "Father";

    public void printName() {
        System.out.println("Father: --- " + name);
    }

    //新加的方法
    public void init() {
        name = "父类";
    }
}

//Son.java
public class Son extends Father {
    public String name = "Son";

    public void printName() {
        System.out.println("Son: --- " + name);
    }
}

//Main.java
public static void main(String[] args) {
    //test 1
    Father son = new Son();
    System.out.println("--- son name is " + son.name);
    son.init();
    son.printName();
    System.out.println("--- son name is " + son.name);

    //test 2
    Son son1 = new Son();
    System.out.println("--- son1 name is " + son1.name);
    son1.init();
    son1.printName();
    System.out.println("--- son1 name is " + son1.name);
}

输出结果:

--- son name is Father
Son: --- Son
--- son name is 父类

--- son1 name is Son
Son: --- Son
--- son1 name is Son

结果说明:第一个son是由Father类定义的,它的属性是Father实例的属性,第二个son1是由Son类定义的,它的属性是Son实例的属性。init()方法是Father的方法,改变的是Father实例的属性。如果我们在init()方法中加句打印System.out.println("name = " + name);,那么两个实例都会打印一个结果name = 父类

【栗子4说明】根据结果我们发现,父类的init()方法改变的还是父类的属性,再进一步验证前面的结果——在的方法中,就会调用(使用/改变)的属性。


栗子5

在栗子4的基础上,让子类重写父类的init()方法,其他代码完全一样

//Father.java
public class Father {
    public String name = "Father";

    public void printName() {
        System.out.println("Father: --- " + name);
    }

    public void init() {
        name = "父类";
    }
}

//Son.java
public class Son extends Father {
    public String name = "Son";

    public void printName() {
        System.out.println("Son: --- " + name);
    }

    //子类重写父类init()方法
    public void init() {
        name = "子类";
    }
}

//Main.java
public static void main(String[] args) {
    //test 1
    Father son = new Son();
    System.out.println("--- son name is " + son.name);
    son.init();
    son.printName();
    System.out.println("--- son name is " + son.name);

    //test 2
    Son son1 = new Son();
    System.out.println("--- son1 name is " + son1.name);
    son1.init();
    son1.printName();
    System.out.println("--- son1 name is " + son1.name);
}

输出结果:

--- son name is Father
Son: --- 子类
--- son name is Father

--- son1 name is Son
Son: --- 子类
--- son1 name is 子类

(测试到这我已经凌乱了……)

【栗子5说明】栗子5再次说明前面几点:
1.属性不具备多态性,谁定义的实例,属性就是属于谁。
2.除非用该类的方法(被重写了不算)更改该实例属性,否则属性不会改变。
3.哪个类的方法(被重写了不算)使用哪个类定义实例的属性
4.也是这篇博文的中心论证:

没事不要让子类重写父类的属性玩,好累……
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值