01_多态的概述
- A:多态(polymorphic)概述
- 事物存在多种形态
- B:多态前提
- a:要有继承关系
- b:要有方法重写
- c:要有父类引用指向子类对象
- C:案例演示
class Demo1_Polymorphic {
public static void main(String[] args) {
Cat c = new Cat();
c.eat();
System.out.println("-----------------------");
Animal a = new Cat(); //多态,父类引用指向子类对象
a.eat();
}
}
class Animal{
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
/*
猫吃鱼
-----------------------
猫吃鱼
*/
02_多态中成员访问特点
- 成员变量
- 编译看左边(父类),运行看左边(父类),都看左边
- 成员方法()
- 编译看左边(父类),运行看右边(子类)
- 静态方法(多态中的成员访问特点之静态成员方法)
- 编译看左边(父类),运行看左边(父类),都看左边
- (静态和类相关,算不上重写,所以,访问还是左边的)
- 只有非静态的成员方法,编译看左边,运行看右边
- 示例:(成员变量)
class Demo2 {
public static void main(String[] args) {
Fu f = new Zi(); //父类引用指向子类对象
System.out.println(f.num);
Zi z = new Zi();
System.out.println(z.num);
}
}
class Fu{
int num = 10;
}
class Zi extends Fu{
int num = 20;
}
/*
10
20
*/
- 示例:(成员方法)
class Demo2 {
public static void main(String[] args) {
Fu f = new Zi(); //父类引用指向子类对象
f.print(); //编译看左边,运行看右边,父类中,如果没有print方法,则报错
Zi z = new Zi();
z.print();
}
}
class Fu{
public void print(){
System.out.println("father");
}
}
class Zi extends Fu{
public void print(){
System.out.println("zi");
}
}
/*
zi
zi
*/
- 示例:(静态方法)
class Demo2 {
public static void main(String[] args) {
Fu f = new Zi(); //父类引用指向子类对象
f.method();
Zi z = new Zi();
z.method();
}
}
class Fu{
public static void method(){
System.out.println("Fu static method");
}
}
class Zi extends Fu{
public static void method(){
System.out.println("Zi static method");
}
}
/*
Fu static method
Zi static method
*/
02_多态中向上与向下转型
- 示例1(没有转型,报错*****)
class Demo1 {
public static void main(String[] args) {
Fu f = new Zi();
f.method();
f.sleep(); //因为编译看左边,运行看右边
//左边没有sleep方法,所有编译就不通过,报错
}
}
class Fu {
public void method(){
System.out.println("Fu method");
}
}
class Zi extends Fu {
public void sleep(){
System.out.println("Zi sleep");
}
}
/*
编译时出现错误
---------- javac ----------
Demo1.java:5: 错误: 找不到符号
f.sleep();
^
符号: 方法 sleep()
位置: 类型为Fu的变量 f
1 个错误
*/
- 示例2(转型)
class Demo1 {
public static void main(String[] args) {
Fu f = new Zi();
f.method();
//f.sleep(); //因为编译看左边,运行看右边
//左边没有sleep方法,所有编译就不通过,报错
Zi z = (Zi)f; //进行向下转型
z.sleep(); //编译看左边,运行看右边
}
}
class Fu {
public void method(){
System.out.println("Fu method");
}
}
class Zi extends Fu {
public void sleep(){
System.out.println("Zi sleep");
}
}
/*
Fu method
Zi sleep
*/
03_多态中好处和弊端
- 示例(多态作为一个参数)
class Demo2_Animal {
public static void main(String[] args) {
method(new Cat());
method(new Dog());
}
public static void method(Animal a){ //主方法中要使用静态
a.eat();
}
}
class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
}
class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
}
/*
猫吃鱼
狗吃肉
*/
04_多态中的强制转换(instanceof)
想调用子类中特有的方法,必须要进行强制转
- 示例(instanceof)
class Demo2_Animal {
public static void main(String[] args) {
method(new Cat());
method(new Dog());
}
public static void method(Animal a){ //主方法中要使用静态
//关键字instanceof判断前面的引用是否是后边的数据类型
if (a instanceof Cat) {
Cat c = (Cat)a;
c.eat();
c.catchMouse();
}else if (a instanceof Dog) {
Dog d = (Dog)a;
d.eat();
d.lookHome();
}
}
}
class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
public void lookHome(){
System.out.println("狗看家");
}
}
/*
猫吃鱼
抓老鼠
狗吃肉
狗看家
*/