一条咸鱼浅讲多态

这里是一条咸鱼的讲解,下面讲述不对之处请谅解。

 

在给同学讲多态的时候,讲了挺久,最后是通过一个面试题(如何正确用代码表达多态)讲清楚的,所以本咸鱼觉得可以记录下来让别的苦恼的同学看能不能有所收获。

 

刚学多态的时候老师总会讲:父类引用指向子类对象就是多态。这句话是个总结,在学多态前其实还应该知道多态的必备条件(先死记)

  • 类与类(或接口与类、接口与接口)之间存在继承关系。
  • 可以进行重写。
  • 父类引用指向子类对象。(虽然这句是总结,但其实也可以算是多态的一个条件)
/*
   有两个类,A和B,A是B的父类 
*/

//我们学多态前(不是多态)
A a = new A();
B b = new B();

//多态
A a = new B();

 

可以很明显的看出讲多态后,= 右边 new 的类型可以和前面不一样了,但这个不一样是有规定的,= 右边必须是左边的子类(或子接口)。

到这就是多态?这是刚学多态很懵逼的时候,感觉听完还是无法讲出多态是个什么。

多态就像你的电脑,除了你的主机,还应该有显示器、鼠标和键盘,它们连起来才能形成一个整体电脑。多态也是这样,你得把其他知识点学完,结合一起才能理解什么是多态。

 

接下讲多态的方法运行:

先上代码看运行结果

public class A {
	
	public void fun(int i) {
		System.out.println("A " + i);
	}
	
}

public class B extends A {
		
	@Override
	public void fun(int i) {
		System.out.println("B " + i);
      }

      public void funB() {
       System.out.println("B funB");
      }
	
}

public class Test {
        public static void main(String[] args) {	
	  A a = new B();	
	  a.fun(10);
       //a.funB(); //编译报错
	}  
}

  

运行结果:

 

 

到这可能有一个问题:不是new的B类吗,怎么调用funB()就报错了。

其实用这段代码讲多态很容易让新人摸不着头脑,下面我们用上文提到的面试题进行解答为什么执行是这样的结果。

先讲结论:编译看左边,运行看右边。

修改代码:这段代码不难,一定要完全看懂才能听懂下面的讲述。

public class A {
	
	public void fun(int i) {
		System.out.println("A " + i);
	}
	
}

//A的子类1
public class B extends A {
		
	@Override
	public void fun(int i) {
		System.out.println("B " + i);
	}

	public void funB() {
		System.out.println("B funB");
	}
	
}

//A的子类2
public class C extends A {
	
	@Override
	public void fun(int i) {
		System.out.println("C " + i);		
	}

}

public class Test {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入0或1:");
		int i = sc.nextInt();

		A a = null;
		switch(i) {
		case 0: a = new B(); break;
		case 1: a = new C(); break;
		}
		
		a.fun(10);
		//a.funB(); //编译报错。
	}

}

  

执行结果:

 

 

我们现在的情况就是A有了两个子类B、C,我们写代码后还得进行编译,编译时Test的main方法还没执行,它是无法知道 a 的右边到底是 new B() 还是 new C() 的,所以编译器只能通过 = 左边的引用类型进行判断 a 进行调用的方法存不存在,a 中都没有 B 的 funB(),那自然也就编译报错,这就是编译看左边

当我们程序进行执行的时候,程序走完switch时自然也就知道到底new的是谁了,a 调用 fun() 时,也就去 = 右边的对象中去找对应的方法执行了,这就是运行看右边

 

讲到这,多态还没完,先上代码:

public class A {
	
	int i = 10;
	
}

public class B extends A {
	
	int i = 20;
	
}

public class C extends A {
	
	int i = 30;

}

public class Test {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入0或1:");
		int i = sc.nextInt();

		A a = null;
		switch(i) {
		case 0: a = new B(); break;
		case 1: a = new C(); break;
		}
		
		System.out.println(a.i);
	}

}

  

执行结果:

 

 

你这条咸鱼自己咸就算了,还骗人,讲的编译看左,运行看右都是骗人的。其实是没讲错的,只是编译看左,运行看右只能适用于方法。下面解释为什么在属性这就行不通了。

别忘了我上文让你死记的多态成立的必备条件,条件中有一条可以进行重写,属性是不存在重写这个概念的(这个是继承的知识),属性也就不存在多态这个概念了,不能运行看右边了,a 是 A 类型,自然也就调用 A 中的属性了。

 

至于重载为什么不是多态,这个我在这就不进行讲述了(说白了就是菜、懒),别人的博客有,弄懂多态,也就能看的懂了。

 

最后再声明一遍,这只是一条咸鱼的见解,有误之处多担待(毕竟我人怂胆子小,技术还菜。。。),学的时候请保持质疑的态度。

posted on 2020-05-23 09:42  浊酒凡尘  阅读(228)  评论(0)    收藏  举报

导航