目录,更新ing,学习Java的点滴记录
目录放在这里太长了,附目录链接大家可以自由选择查看--------Java学习目录
多态_概念和实现
- 在面向对象的程序设计语言中,多态是继封装和继承之后的第三种基本特征
- 有一个简单的规则,可以用来判断是否应该将数据设计为继承关系,这就是"is-a"规则,它表明子类的每个对象也是超类的对象.例如,每个经理都是雇员,因此,将Manager类设计为Employee类的子类是显而易见的.反之不然,因为并不是每一名雇员都是经理
- "is-a"规则的另一种表述法是
置换法则
.它表明程序中出现父类对象的地方都可以用子类对象置换
,例如:
- 在Java中,对象变量是多态的.一个Employee类型变量既可以引用一个Employee类型变量也可以引用一个Employee的任何子类对象,这就是常说的------
父类引用指向子类对象
多态指的是同一个方法调用
,由于对象不同可能会有不同的行为。现实生活中,同一个 方法,具体实现会完全不同。 同样是调用人“吃饭”的方法,中国人用筷子吃饭,英国人用刀叉吃饭.- 要点
1.多态是方法的多态
,不是属性的多态(多态与属性无关)。
2.多态的存在要有 3 个必要条件
:继承,方法重写,父类引用指向子类对象。
3.父类引用指向子类对象后,用该父类引用调用子类重写的方法
,此时多态就出现了 - 多态示例
package com.m1;
public class Test {
/**
* 有了多态,只要将增加的类如Dog,Cat继承Animal类
* 那么这个run方法就可以同时处理这个类族中所有的类型的方法调用
* @param animal 传递的实参只要是Animal及其子类
*/
static void run(Animal animal){
animal.run();
}
/**
* 如果没有多态,就需要写很多重载方法
*/
// static void run(Dog dog){
// dog.run();
// }
//
// static void run(Cat cat){
// cat.run();
// }
public static void main(String[] args) {
Animal a1 = new Dog(); //父类引用指向子类对象,可以向上自动转型
//传递的是哪个类就调用哪个类的方法,大大提高了程序的可扩展性
// a1,a2为编译类型,Dog和Cat对象才是运行时类型
run(a1);
Animal a2 = new Cat();
run(a2);
/*
编写程序时,如果想要调用运行时类型的方法,
只能进行强制类型转换.否则通不过编译器的检查
*/
Dog dog = (Dog)a1; //向下需要强制类型转换
dog.run();
}
}
上述代码中可以看出多态的一种最常见的用法,即父类引用做方法的形参,实参可以是父类及其子类对象,可以通过不同的子类对象实现不同的方法调用结果.
我们可以看出多态的主要优势是提高了代码的可扩展性,符合开闭原则。但是多态也有弊端,就是无法调用子类特有的功能,比如,我不能使用父类的引用变量调用 Dog 类特有的 seeDoor()方法
。如果想要使用子类特有的功能,那就得需要使用对象的转型.
多态_对象的转型
- 父类引用指向子类对象,我们称这个过程为
向上转型
,属于自动类型转换。 - 向上转型后的父类引用变量
只能调用它编译类型的方法,不能调用它运行时类型的特有方法
。这时,我们就需要进行类型的强制转换,我们称之为向下转型
- 将一个子类引用赋给一个父类变量编译器是允许的.但反之将一个父类引用赋给一个子类变量,必须进行类型转换,这样才能通过运行时的检查.此外,在进行类型转换之前,可以
先查看一下能否成功地转换
,这个过程使用instancof运算符
就可以是实现. - 类型转换示例
在向下转型过程中,必须将引用变量转成真实的子类类型(运行时类型)
否则会出现类型转换异常 ClassCastException。
为了避免出现这种异常,我们可以使用instanceof 运算符
进行判断,它的作用是测试它左边的对象是否是它右边的类,或者其子类、实现类的实例