Java面向对象特性-多态(详解)

多态

含义:顾名思义,是指对象的多种形态,是对象多种表现形式的体现。

多态是建立在封装和继承之上 。


 多态存在的三个必要条件

1.必须存在 继承 或 实现。

2.子类中重写父类的方法。

3.父类引用指向子类对象(向上转型)。

  •  多态有两种:方法的多态和对象的多态。

方法的多态

方法的重写和重载就是方法的多态的表现形式。

class Father {   //父类
	public void eat() {
		System.out.println("吃米饭");
	}
	public void eat(String food) {
		System.out.println("父类吃:" + food);
	}
}
class Son extends Father{   //子类
	@Override
	public void eat() {
		System.out.println("吃面条");
	}
	@Override
	public void eat(String food) {
		System.out.println("子类吃:" + food);
	}
}
public class Demo1 {

	public static void main(String[] args) {
		Father father = new Father();
		father.eat();
		
		Father father1 = new Father();
		father1.eat("吃牛肉");
		
		Son son = new Son();
		son.eat();
		  
		Son son1 = new Son();
		son1.eat("鸡肉");
	}

}

 对象的多态

  1. 一个对象的编译类型和运行类型是不同的
  2. 编译类型是在定义对象的时候就已经确定好的,但运行类型是可以改变的
  3. 编译类型看 “=” 的左边,运行类型看 “=” 的右边

 父类的引用指向子类的对象

   Animal an = new Tiger();

   Animal an1 = new Cat();

class Animal {
	public void cry() {
		System.out.println("动物的叫声");
	}
}
class Tiger extends Animal {
	@Override
	public void cry() {
		System.out.println("老虎的叫声很大");
	}
}
class Cat extends Animal {
	@Override
	public void cry() {
		System.out.println("小猫的叫声很小");
	}
}



public class Demo1 {

	public static void main(String[] args) {
		Animal an = new Tiger();   //Animal类的引用指向Tiger类引用
		an.cry();
		Animal an1 = new Cat();
		an1.cry();
	}

}

在开发中,一个方法的参数是父类的引用。但是真正传的值是子类的对象。 将子类的对象赋值给了父类的引用。

//面馆类
class NoodleShop {
	public void choice(Nodle nodle) {
		nodle.make();
	}
}

//面条类
class Nodle {
	private String name;
	private double price;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public void make() {
		
	}
}

//牛肉面类
class BeefNoodles extends Nodle {
	@Override
	public void make() {
		System.out.println("制作面条的名称:" + getName() + ",价格:" + getPrice());
	}
}


//鸡肉面类
class ChickenNoodles extends Nodle {
	@Override
	public void make() {
		System.out.println("制作面条的名称:" + getName() + ",价格:" + getPrice());
	}
}



public class Demo1 {

	public static void main(String[] args) {
		NoodleShop noodleShop = new NoodleShop();
		Nodle nodle = new BeefNoodles();
		nodle.setName("牛肉面");
		nodle.setPrice(58.1);
		noodleShop.choice(nodle);
		Nodle nodle1 = new ChickenNoodles();
		nodle1.setName("鸡肉面");
		nodle1.setPrice(49.9);
		noodleShop.choice(nodle1);
 }
}

多态的转型

向上转型和向下转型。

向上转型

本质:父类的引用指向子类对象 。

语法格式:

父类 父类引用 = new 子类();

 

父类的引用可以调用父类的所有成员方法,可以调用子类的重写父类的方法,但是不能调用子类独有的方法。

class Person {
	public void eat () {
		
	}
}

class Student extends Person {
	@Override
	public void eat() {      //子类重写父类的方法
		System.out.println("学生吃饭,吃披萨");
	}
	public void sleep () {
		System.out.println("中午不睡下午崩溃!!!");
	}
}

public class Demo1 {
	public static void main(String[] args) {
		Person person = new Student();   //向上转型
		person.eat();
		//person.sleep();  //父类无法调用子类独有的方法
	}

}

向下转型

需要强转

  •         注意点:先向上转型,再向下转型

语法格式:

父类类型 父类引用 = new  子类();     //父类引用指向了子类的对象,子类赋值给父类引用


子类类型 子类引用 = (子类类型)父类的引用;向下转型   //将父类的引用赋值给子类,父类赋值给子类引用

//引用上面的animal、tiger和cat
Animal a = new Tiger();
Tiger tiger = ((Tiger) a);
tiger.cry();
//输出  老虎的叫声很大

Cat cat = ((Cat) a);
cat.cry();
// 报错 

Animal a1 = new Animal();
Cat cat1 = ((Cat) a1);
cat1.cry();
// 报错 

第一段代码之所以不报错,是因为先将子类对象赋值给父类引用了,a本身就是Tiger类的对象,在此之后再向下转型。

而a1为父类Animal的对象,它不能被向下转型为任何子类对象。

你可能感兴趣的:(开发语言,java)