继承结合向上转型的好处
方法重写,适应不同的子类
对于父类来说,统一规范好子类常用的属性和方法。
针对不同的子类能够根据子类的情况适当的重写属性和方法,同时能够增加一些属性和方法。
父类代码:
/**
* 父类
*/
public class Person {
// 将要被子类重写的属性
int age;
// 将要被子类重写的方法
public void say() {}
// 没有被子类重写的方法
public void dance() {
System.out.println("我喜欢跳舞!");
}
}
子类1代码:
/**
* 子类1
*/
public class Son_1 extends Person{
// age属性被子类1重写
int age = 6;
// say方法被子类1重写
public void say() {
System.out.print("我是大儿子!");
}
}
子类2代码:
/**
* 子类2
*/
public class Son_2 extends Person{
// age属性被子类2重写
int age = 4;
// say方法被子类2重写
public void say() {
System.out.print("我是二儿子!");
}
}
父类为子类提供了子类公共的属性和方法,如果不重写,则使用的是父类的方法体和属性值,这样各个子类就无需多次重复写公用不变的属性和方法
向上转型,统一调用子类的属性和方法
首先在理解向上转型的好处之前我们来了解下,向上转型和不向上转型以及向下转型的区别:
- 子类向父类转型:`
// 向上转型
Person son_1 = new Son_1();
// 可以向下强制转型
Son_1 temp = (Son_1) son_1;
// 能够输出hobby属性,未报错(说明类型变化后,变量仍然指向子类地址)
System.out.println(temp.hobby);
- 父类向子类转型:
// 直接新建父类类型的对象
Person person = new Person();
// 能够进行向下转型,不过执行报错(说明类型变化后,变量仍然指向父类地址)
Son_1 son = (Son_1) person;
System.out.println(son.hobby); // 该语句报错
说明,即使类型变化了,但是变量的指向地址并没有发生改变。
- 对于继承来说,向上转型的好处有哪些?
未向上转型:
public static void main(String[] args) {
Son_1 son_1 = new Son_1();
Son_2 son_2 = new Son_2();
// 当不知道输入的对象是何种类型时,introduce需要把所有的子类类型都写一遍
introduce(son_1);
introduce(son_2);
}
// 下面为introduce的重载方法,可能出现的有两种类型子类,则重载两遍
public static void introduce(Son_1 son_1) {
son_1.say();
System.out.print("今年"+son_1.age+"岁了");
}
public static void introduce(Son_2 son_2) {
son_2.say();
System.out.print("今年"+son_2.age+"岁了");
}
此时可以看出,如果子类的类型比较多的话,则需要写好多introduce的方法,这很繁琐。
那如何通过一个introduce将所有的子类都包括呢?
向上转型:
public static void main(String[] args) {
// 子类向父类转型
Person son_1 = new Son_1();
Person son_2 = new Son_2();
introduce(son_1);
introduce(son_2);
}
// 为了统一调用被子类重写的公共属性和方法,此方法只写了一遍
public static void introduce(Person per) {
per.say();
System.out.print("今年"+per.age+"岁了");
}
从代码可以看出,introduce只写了一遍,可以将所有子类包括,这提高了代码的简洁性。