多态作为java面向对象特征之一,非常重要;可以说,java面向对象的核心就是通过多态实现的。
面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
如果没有多态,前两个很多时候都没有必要。
多态的作用:
1.消除类型之间的耦合关系,也就是实现低耦合。
2.多态的出现大大的提高程序的扩展性,但是只能使用父类的引用访问父类中的成员。
多态存在的三个必要条件:
一、要有继承(类)或者实现(接口);
二、要有重写(方法);
三、父类引用指向子类对象(这样运行时就能根据实际创建的对象类型动态决定使用哪个方法)。
多态分两种:
1.编译时多态(静态多态性):编译时动态重载;
2.运行时多态(动态多态性):指一个对象可以具有多个类型。
编译时类型,也就是可以被看作的类型,主观认定。
运行时类型,也就是实际的对象实例的类型,客观不可改变(也是被看作类型的子类型)
对于一个对象来说,在对象产生时,运行时类型就已经确定不会再改变,编译时类型可以和运行时类型不同。在对象变量声明时可以确定其运行时类型,但是编译时类型对象变量背后所指向运行时类型则可以是其本类型或者是其子类型。
多态三特性
1,对象实例确定则不可改变(客观不可改变)
2,只能调用编译时类型所定义的方法。
3,运行时会根据运行时类型去调用相应类型中定义的方法。
多态的意义:在需要使用一类对象的共性时,可以用多来屏蔽掉其子类中的差异。
注意:类的属性是没有多态的,只会根据编译时类型访问。只有子类覆盖了父类的方法,且把子类对象党作父类类型来看时才会有多态。要注意区分子类中的方法重载。对于方法的重载,则是会使用编译时类型来进行相应的方法调用。
两种复用
白箱复用,也就是继承复用,父类中的可以被子类访问到的就可以被继承,这样会有些不需要的内容被继承下来,所以这种方式不太好。
黑箱复用,也叫组合复用,也就是把要复用代码的类的对象作为本类中的一个属性,然后再通过方法的委托来实现由选择的复用,方法的委托就是在本类的方法内部通过该类的对象调用要使用类的方法。
注意:尽量用组合复用替代继承复用。
多态的使用
多态用于参数,可以在方法的参数中传入其父类类型,在运行时会根据实际的运行时类型来在方法中进行相应的操作。
多态用于返回值,可以在方法的返回值类型上是用其实际返回值的父类型,在使用期返回值时也不比关心其实际类型。
多态可以使代码变得更通用,以适应需求的变化。也就是定义在父类中的方法,可以在子类中有不同的实现将其覆盖,在为父类型的对象变量赋值相应需要功能的子类的对象实例。
父类与子类对象编程规则(赋值兼容原则):子类的对象可当着父类的对象来使用。
以下是我的代码实例:
package cn.java.test.Three_big_characteristics;
/**
* 这里是讲解java三大特性的常用的一个:多态。
* 多态是具有表现多种形态的能力特征,也可以说,共同实现一个接口或父类的类,却具有不同的具体实现而执行不同的操作。
* 在JAVA中有两种多态是指:运行时多态和编译时多态。
* 1.编译时多态:编译时动态重载;
* 2.运行时多态:指一个对象可以具有多个类型。
*
* 开发中常用常说的多态是指运行时多态;
*
* 多态性是面向对象的核心特征之一,类的多态性提供类中成员设计的灵活性和方法执行的多样性.
*
* 在java中很多地方都用到了多态,其实在java程序设计开放中多态占领者举足轻重的地位。
* 比如很多设计模式中的装饰,当然还有很多比如框架的设计很多地方真的没多态不行。
*
* @author Administrator
*
*/
public class The_Third_polymorphic {
public static void main(String[] args) {
//运行时多态
/*
* Cat和Dog同样都是都是继承父类Animal_class,由于各自实现不同,所以在我们把多个子类的对象指向为父类
* 引用时(子类具有和父类同样的属性和行为,有同一类的特征,因此能够代替父类;
* 如:猫,狗(子类)都是动物(父类);白马,黑马(子类)都是马(父类)),父类的表现行为就具有多样性。
*/
System.out.println("----------------运行时多态----------------\n");
//定义一个猫类对象指向父类;
Animal_class myAnimal_class01 = new Cat();
myAnimal_class01.say();
System.out.println("我有:" + myAnimal_class01);
//定义一个狗类对象指向父类;
Animal_class myAnimal_class02 = new Dog();
myAnimal_class02.say();
System.out.println("我有:" + myAnimal_class02);
//编译时多态
System.out.println("\n\n----------------编译时多态----------------\n");
Dog dog=(Dog) myAnimal_class02;
dog.feed();
dog.feed("大大的骨头");
}
}
//用父类属性和行为约束子类;
abstract class Animal_class {
String Attribute01 = "眼睛";
String Attribute02 = "鼻子";
String Attribute03 = "耳朵";
//说话方法;
abstract void say();
//吃东西方法;
abstract void feed();
}
class Cat extends Animal_class {
String Attribute03 = "小耳朵";
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("喵,喵,喵,喵.......");
}
@Override
public String toString() {
// TODO Auto-generated method stub
return Attribute01 + ":" + Attribute02 + ":" + Attribute03;
}
@Override
public void feed() {
// TODO Auto-generated method stub
System.out.println("我吃鱼....");
}
}
class Dog extends Animal_class {
String Attribute03 = "大耳朵";
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("汪,汪,汪,汪......");
}
@Override
public void feed() {
// TODO Auto-generated method stub
System.out.println("我吃天津狗不理包子.....");
}
public void feed(String feed) {
// TODO Auto-generated method stub
System.out.println("我还吃:"+feed);
}
@Override
public String toString() {
// TODO Auto-generated method stub
return Attribute01 + ":" + Attribute02 + ":" + Attribute03;
}
}
控制台信息打印:
----------------运行时多态----------------
喵,喵,喵,喵.......
我有:眼睛:鼻子:小耳朵
汪,汪,汪,汪......
我有:眼睛:鼻子:大耳朵
----------------编译时多态----------------
我吃天津狗不理包子.....
我还吃:大大的骨头