您的位置:首页 > 编程语言 > Java开发

Java复习之多态

2018-03-22 20:07 148 查看

Java复习之多态

多态:可以理解为事物存在的多种体现形态。举个简单的例子就是人有男人和女人;动物有猫狗等

下面通过几个方面来理解多态这一特性。具体如下:

1.多态的体现:

父类的引用指向了自己的子类对象;换言之,父类的引用也可以接收自己的子类对象。


2.多态的前提:

必须是类与类之间有关系,要么继承,要么实现。

通常还有一个前提:存在覆盖,就是说子类存在对父类函数的重写或者是实现。

3.多态的好处:

多态的出现大大的提高了程序的扩展性。

abstract class Animal{
public abstract void eat();
}
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 kanJia(){
System.out.println("看家");
}
}
//测试一下

Animal a1=new Cat();//类型提升:向上转型。
a1.eat();
Cat c1=(Cat)a1;//强制将父类的引用转成子类类型:向下转型,调用猫自己特有的方法
c1.catchMouse();
运行结果为:吃鱼  抓老鼠

--------------------------------------------------------------

//下面的两行代码体现了扩展性:以后再有别的动物,就可以把新动物的类组
//建好,然后通过function函数来调用即可,大大提高了程序的扩展性。
function1(new Cat());
function1(new Dog());
public static void function1(Animal a){
a.eat();
}
运行结果为:吃鱼 吃骨头

------------------------------------------------------
/*千万不要将父类的对象转换成子类类型,我们转换的是父类引用指向了子类
对象时,该应用可以被提升,也可以被强制转换。所以多态自始至终都是子类
对象在做着变化*/

Animal a2=new Animal();//这里假设Animal不是抽象类
Cat c2=(Cat)a2;
//这种转型不存在,不可能把动物转成猫,因为动物是啥不确定!


4.多态的弊端:

提高了扩展性,但是只能使用父类的引用访问父类中的成员。(原因就是下面6所讲的,简单说就是父类中没有的成员如果父类调用了,编译时是要出错的,而且就算用子类的成员也需要进行向下转型)

5.多态的应用:

/*举一个例子来体现多态的应用。比如电脑主板有很多插口,那么对于显卡的那个
口,显卡的牌子是很多的,但是为了电脑主板可以带的起来,显卡本身就得符合
一种规范,我们把这个规范定义为接口,在主板类中就可以通过多态来接收各种各样
的只要符合主板使用规范的显卡即可。而且也体现了一定的扩展性,新的配件只要
符合规范就可以用。*/
interface PCI{
public void open();
public void close();
}

class MainBoard{
public void run(){
System.out.println("MainBoard Run");
}
//相当于PCI p=new NetCard();即接口型引用指向自己的子类对象。
public void usePCI(PCI p){//多态的应用用!!!!
if(p!=null){
p.open();
p.close();
}
}
}
//显卡的使用必须符合接口才能让主板来使用,所以要实现接口PCI
class NetCard implements PCI{
public void open(){
System.out.println("NetCard Open");
}
public void close(){
System.out.println("NetCard Close");
}
}


6.多态的出现代码的特点(多态使用的注意事项):

1).在多态中成员函数的特点:

在编译时期:参阅引用型变量所属的类中是否有调用的方法;如果有编译通过,否则编译失败!

在运行时期:参阅对象所属的类中是否有调用的方法。

把a的说法简言之:成员函数在多态调用时,编译看左边,运行看右边。

2).在多态中成员变量的特点:

无论编译和运行,都参考左边(引用型变量所属的类)。

3).在多态中静态成员或者静态函数的特点:

无论编译和运行,都参考左边。

注意:2)和3)在开发是不多见,就a多见,所以使用时要注意一下!


简单总结一下,在看demo。自我认为静态一定是绑定类存在的,一般是习惯用类来调用,并且调用的也是该类中的内容;但是非静态是靠对象动态绑定类的,所以调用时运行的是对象所在类的内容。

class Fu{
int num1=5;
static int num2=6;
void method1(){
System.out.println("fu method1");
}
void method2(){
System.out.println("fu method2");
}
static void method4(){
System.out.println("fu method4");
}
}
class Zi extends Fu{
int num1=8;
static int num2=9;
void method1(){
System.out.println("zi method1");
}
void method3(){
System.out.println("zi method3");
}
static void method4(){
System.out.println("zi method4");
}
}
//测试一下
Fu f=new Zi();//父类的引用指向了子类的对象。
f.method1();//打印结果:zi method1
f.method2();//打印结果:fu method2(子类没有复写method2方法,所以直接继承父类的方法)
//f.method3();
/*在编译时期需要参阅引用型变量所属的类中是否有调用的方法;
如果有编译通过,否则编译失败!所以f调用1和2能通过,调用3
却通过不了,在运行时期需要参阅对象所属的类中是否有调用的方
法,所以打印结果分别为zi method1;fu method2*/

Fu eg1=new Zi();
System.out.println(eg1.num1);//打印结果:5
Zi eg2=new Zi();
System.out.println(eg2.num1);//打印结果:8
//在多态中成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)

Fu eg3=new Zi();
System.out.println(eg3.num2);//打印结果:6
Zi eg4=new Zi();
System.out.println(eg4.num2);//打印结果:9

Fu eg5=new Zi();
eg5.method4();//打印结果:fu method4
/*以上的结果显示了在多态中静态成员和静态函
数的特点:无论编译和运行,都参考左边*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 多态 对象