小白学习JavaSE-day07之多态

多态

1、多态介绍

多态:某个事物(物体)采用不同的形态表示(描述)。针对这个事物或个体(实例)称为它发生了多态的现象。

一个事物的多种形态。

例如:

饭很好吃:针对具体到的是什么饭,然后这个饭被使用笼统的方式描述。

水果:苹果、西瓜、香蕉等。

动物:可能面对的是一只猫,但这个小动物很可爱。猫就发生多态,如果说猫很可爱,猫就用自己本身形态表示。

不管什么物种,采用什么形式描述,但是这个物种永远不会发生变化。

2、在Java中多态的体现

Java中如果要能够发生多态现象,必须有继承或者实现的存在

一个类应该有父类或者有接口。否则无法使用多态。

多态的代码体现:

  • 父类类型或接口类型 变量名 = new 子类或实现类( ) ;
  • 父类类型或接口类型 变量名 = 引用变量;
class Animal{
     
	
}
class Dog extends Animal{
     
	
}
public class Demo {
     
	public static void main(String[] args) {
     
		//	没有发生多态
		Dog d = new Dog();
		//	多态的体现
		Animal a = new Dog();
		//	多态
		Animal a2 = d;
	}
}

只要是父类或接口的引用变量指向了子类或者实现类对象,都是多态。

3、多态的使用

abstract class Animal{
     
	//	描述的是所有动物共性的eat行为
	public abstract void eat();
}
//	缉毒的接口
interface AntiDrug{
     
	public void antiDrug();
}
//	Dog经过后天训练具备缉毒的行为
class Dog extends Animal implements AntiDrug{
     
	public void eat() {
     
		System.out.println("啃骨头");
	}
	//	复写缉毒的行为
	public void antiDrug() {
     
		System.out.println("狗缉毒");
	}
	//	看家
	public void lookHome() {
     
		System.out.println("小狗看家");
	}
	
	
}
class Cat extends Animal{
     
	public void eat() {
     
		System.out.println("吃鱼");
	}
}
//Pig经过后天训练具备缉毒的行为
class Pig extends Animal implements AntiDrug{
     
	public void eat() {
     
		System.out.println("吃糠");
	}
	//	复写缉毒的行为
	public void antiDrug() {
     
		System.out.println("猪缉毒");
	}
}

public class InterfaceDemo2 {
     
	public static void main(String[] args) {
     
		//	多态
		Animal a = new Dog();
		//	多态之后,只能调用父类或者接口中公共的方法
		a.eat();
		//	多态之后,无法调用子类中特有的方法
		//a.lookHome();
		//	如果已经明确知道多态所指的对象的具体类型,
		//	可以将整个多态的引用进行强转
		Dog d = (Dog)a;
		d.lookHome();
		
		run( new Dog() );
		
	}
	//	这个方法接受的参数一定是Animal的子类对象
	//	只要下面run方法被调用,一定会发生多态的参数传递
	public static void run( Animal a) {
      //	Animal a = new Dog();
		a.eat();
	}
}

4、多态的细节

  • 非静态方法:编译的时候要求父类或接口中必须拥有这个方法,但是运行的时候执行的子类或者实现类复写后的方法。(编译看父类,运行看子类)
  • 变量:编译运行都是使用父类或接口中的(编译运行都是父类)
  • 静态方法:多态下调用静态方法,编译和运行都是父类中(编译运行都是父类)
class Fu{
     
	int x = 12;
	public void run() {
     
		System.out.println("Fu run .... ");
	}
	public static void method() {
     
		System.out.println("Fu method ....");
	}
}
class Zi extends Fu{
     
	int x = 34;
	public void run() {
     
		System.out.println("Zi run .... ");
	}
	public static void method() {
     
		System.out.println("Zi method ....");
	}
}
public class Demo {
     
	public static void main(String[] args) {
     
		//	没有多态
		Zi z = new Zi();
		z.run();
		//	多态中的方法调用
		Fu f = new Zi();
		f.run();
		//	针对变量,编译运行都是父类中的
		System.out.println( f.x );
		
		//	静态方法通过类名直接调用
		Zi.method();
		Fu.method();
		//	多态下调用静态方法,编译和运行都是父类中
		f.method();
	}
}

5、多态中的转型

多态发生之后,子类对象被父类或者接口类型引用。

  • 向上转型:父类或接口引用 指向 子类或实现类对象
  • 向下转型:将父类或接口引用类型转成具体的子类或实现类类型。

如果使用的行为(方法)在A 类中已经存在(抽象方法),这时就可以任意找到A类某个子类创建对象,然后使用A类的类型进行引用。调用方法执行。

public class DemoTest {
     
	public static void main(String[] args) {
     
		/*
		 * 	什么时候使用向上转型:
		 * 	在程序调用的时候,我们只关注父类或者接口中的内容,而不去具体使用子类或实现类中的特有行为时
		 * 	可以直接将某个子类或实现类对象赋值给接口或父类引用。
		 */
		//	向上转型
		Animal a = new Dog();
		Animal a2 = new Cat();
		Animal a3 = new Pig();
		
		/*
		 * 	什么时候使用向下转型:
		 * 	程序中需要使用子类或实现类中特有的行为,需要将父类或接口引用转成子类或实现类类型
		 */
		//	向下转型(强制类型转换)
		Dog d = (Dog) a;
		
	}
}

向下转型有风险:

//	多态
A a = new C();
//	向下转型
C c = (C)a;
//	如果现在不清楚a引用指向具体是哪个子类类型
B b = (B)a;  // 这里一定会报错
public class DemoTest2 {
     
	public static void main(String[] args) {
     
		Animal a = new Dog();
	
		Cat c = (Cat) a;
	}
}

小白学习JavaSE-day07之多态_第1张图片

程序中遇到ClassCastException异常,都是进行类型转成时发生。将一种不是当前类型的对象(引用)强转成了当前类型。

public class DemoTest2 {
     
	public static void main(String[] args) {
     
		Animal a = new Dog();
		//	会发生类型转转异常
		//Cat c = (Cat) a;
		/*
		 * 	在进行类型转换的时候,可以进行预先的判断
		 * 	instanceof  判断某个引用是否指向了指定的类型,如果是返回true,否则false
		 */
		if( a instanceof Cat ) {
     
			Cat c = (Cat) a;
			//	通过c调用Cat中的特有方法
		}
		if( a instanceof Dog ) {
     
			Dog d = (Dog) a;
		}
		if( a instanceof Pig ) {
     
			Pig p = (Pig) a;
		}
	}
}

你可能感兴趣的:(学习,多态,javase)