欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java多态初了解

程序员文章站 2022-06-27 16:31:05
一、多态的定义:面向对象程序设计的三大支柱是封装、继承和多态。多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同的操作。用更通俗的话来讲,就是具体问题具体分析。二、首先我们来看一段代码来具体感受一下:public class Test { public static void main(String[] args) { util a = new util(); a.use(); keyboard...

本文主要简述Java中多态的一些基础知识。鉴于本人也是初步了解,若有错误,希望各位大神还能够加以指证。

一、多态的定义:

面向对象程序设计三大特性封装、继承和多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同的操作

用更通俗的话来概况多态,那就是具体问题具体分析

二、实现多态的必要条件

1、 首先我们来看一段基于继承实现多态的代码:

public class Test {
    public static void main(String[] args) {
        util a = new util();
        a.use();
        keyboard b = new keyboard();
        b.use();
        util c = new mouse();
        c.use();
        util d = new computer();    //向上转型
        d.use();
        d.notUse();
        mouse f = (mouse) c;        //向下转型
        f.use();
        f.notUse();
        f.click();
        
        computer k = (computer) c;  //错误的写法
        k.use();                    //因为c此时指向的是子类mouse
    }
}

/** 父类 */
class util {
    public void use() {
        System.out.println("使用工具");
    }
    public void notUse() {
        System.out.println("不使用工具");
    }
}

/** 三个子类 */
class keyboard extends util{
    public void use() {
        System.out.println("使用键盘");
    }
}

class mouse extends util{
    public void use() {
        System.out.println("使用鼠标");
    }
    public void click() {
        System.out.println("点击");
    }
}

class computer extends util{
    public void use() {
        System.out.println("使用电脑");
    }
}

具体输出结果如下:
Java多态初了解

在这段代码中,我们有一个父类,叫做util。

以及还有三个子类,分别是keyboard,mouse,computer,他们都隶属于util这个大类。

而且,我们会发现他们都有一个相同的方法名叫做use。

但现在如果要你在不修改父类的程序代码前提下,同时我们又需要在不同的情况下使用同一个方法名,那该怎么做呢?

如果我们直接删除某个子类的use函数会怎么样呢?结果就是直接调用了父类的use函数并且输出了“使用工具”,这就是继承,但也就达不到输出具体实例需要的效果了。

这个时候就需要多态性,即不修改程序代码就可以改变程序运行时所绑定的具体代码,也可以让程序选择多个运行状态来达到不同的效果。

所以,我们可以得出实现多态的三个必要条件

1、继承
子类首先要继承父类。

2、重写
为了实现具体实例的不同效果,子类需要对继承于父类的同一个方法进行重写,比如代码中的每个子类对父类use方法的重写。

3、转型
转型又可以分为向上转型向下转型

------向上转型具体请看代码中变量d的使用

就是将子类对象转化为父类类型,也可以说父类引用指向子类对象。即 父类类型 对象名称 = new 子类类型()
Java多态初了解

变量d重写了父类的use方法,但是仍旧能使用父类的另一个方法notUse,这大大提高了拓展性。

但同时也有缺点,我们不能再调用子类中的方法和属性了。

所以向上转型主要适用于不需要面向子类对象时,用父类的功能即可完成相应操作的情况。

------向下转型具体请看代码中变量f和k的使用

就是将父类类型强制转化为子类类型。即我们先定义了一个父类对象指向了子类类型,然后将这个父类类型强制转化为子类类型。
Java多态初了解
Java多态初了解

于是向下转型就能够调用子类中的方法,比如变量f的click方法。同时也继承了父类的特点,如图中变量f继承了父类c的use和notUse方法。

所以向下转型主要适用于需要使用子类的功能的情况。

但前提这个子类必须是你这个父类引用时指向的那个子类对象

也就是说你原本是mouse,那你肯定不能变成computer啊。

否则就会出现无法强制转化类型的错误,即出现如下图所示的报错。
Java多态初了解

Java多态初了解
Java多态初了解
2、 我们再来看一段基于接口实现多态的代码:

/** 接口方法创建 */
interface Operation {
	public void add();
	public void delete();
}
 
/** 接口实现类 */
class InterfaceOfUtil implements Operation {
	public void add() { 
		System.out.println("添加工具");
	}
 
	public void delete() {
		System.out.println("删除工具");
	}
}

class InterfaceOfMouse implements Operation {
    public void add() { 
		System.out.println("添加鼠标");
    }
    
	public void delete() {
		System.out.println("删除鼠标");
	}
}

/** 测试类 */
public class Test {
	public static void main(String[] args) {
        Operation op1 = new InterfaceOfUtil();
        Operation op2 = new InterfaceOfMouse();
        op1.add();
        op1.delete();
        op2.add();
        op2.delete();
    }
}

具体输出结果如下:
Java多态初了解
1. 我们首先定义了一个接口,叫做Operation,里面有两个抽象方法,分别是add、delete,用于添加操作和删除操作。
(注意接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法)

2. 我们通过两个接口实现类: InterfaceOfUtil、InterfaceOfMouse,具体实现了接口中的抽象方法。

3. 然后我们通过测试类: Test将两者的操作都使用了一遍。

在这个过程中,我们会发现util和mouse其实都属于可操作的operation类型,在一种类型下表现出了多种状态,比如util和mouse的名字状态就不一样,当然还可以是价格等其他属性等等,这也体现了多态性

三、接下来是根据经典实例略加修改的一段代码:

(借鉴于java提高篇(四)-----理解java的三大特性之多态

public class Test {
    public static void main(String[] args) {
        util father = new util();
        util fatherFromSon = new mouse();
        mouse son = new mouse();
        temp1 t1 = new temp1();
        temp2 t2 = new temp2();

        father.use(son);
        father.use(t1);
        father.use(t2);
        System.out.println("---------");
        fatherFromSon.use(son);
        fatherFromSon.use(t1);
        fatherFromSon.use(t2);
        System.out.println("---------");
        son.use(son);
        son.use(t1);
        son.use(t2);
    }
}
/** 父类 */
class util {
    public void use(temp2 obj) {
        System.out.println("使用工具和temp2");
    }
    public void use(util obj) {
        System.out.println("使用工具和工具");
    }
}

/** 子类 */
class mouse extends util{
    public void use(mouse obj) {
        System.out.println("使用鼠标和鼠标");
    }
    public void use(util obj) {
        System.out.println("使用鼠标和工具");
    }
}

class temp1 extends mouse {
}

class temp2 extends mouse {
}

具体输出结果如下:
Java多态初了解
这里我们有四个类,分别是util、mouse和temp1、temp2。

对于第三个操作,因为temp2有明确定义的方法,所以调用的是use(temp2 obj)这个方法。
Java多态初了解

最难理解的是其他几个操作。例如第四个操作(fatherFromSon.use(son)),fatherFromSon是向上转型的util类型,其use方法重写为son的use方法,按上面的知识点来说,当我们调用use(mouse obj)方法时,应该是输出“使用鼠标和鼠标”的,但结果却是“使用鼠标和工具”,这是为什么呢?

这里就会涉及到继承链中的优先级原则1.this.use(obj)、2.super.use(obj)、3.this.use((super)obj)、4.super.use((super)obj)

那么根据下面这张关系图,

1.首先对于fatherFromSon,它是向上转型的util类型,而util类型中并没有use(mouse obj)这个方法。

2.我们会接着去找util类型的super类,util类已经没有super了,那么就会继续判断下一个优先级。

3.this.use((super)mouse),就等价于this.use(util),由于当前的use方法被重写了,所以就会调用mouse类中的use(util obj),也就输出“使用鼠标和工具了”。

我们会发现其他的几个操作也都是符合这个规律的。
Java多态初了解
如果我们在父类util里面把每个类型的方法都加上,例如下图:
Java多态初了解
那么输出结果就会变成:Java多态初了解
个人理解:如果父类和子类中有相同定义的方法,那么方法就会被成功重写。否则就会按照继承链的优先级来确认方法。

四、多态的优点和缺点:

------优点:

1.可替换性(substitutability): 多态对已存在代码具有可替换性。例如,我们可以通过mouse子类重写方法来实现替换util父类的use方法。

2.可扩充性(extensibility): 多态对代码具有可扩充性。比如我们可以继承父类util的方法,然后继续扩充子类mouse的方法。

3.接口性(interface-ability): 多态中的父类可以通过方法,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。

4.灵活性(flexibility): 它在应用中体现了灵活多样的操作,提高了使用效率。

5.简化性(simplicity): 多态简化了类之间的关系,减少了代码量。

------缺点:

1. 如果不进行向下转型,就无法使用子类的特定功能。

五、总结:

多态是Java中的重要特性。在项目中运用也会有出色的效果,比如在特定的情况下,当某处代码的修改会牵连到很多地方的时候,通过多态的特点来降低耦合度,可以保证程序的拓展性以及降低成本

本文地址:https://blog.csdn.net/m0_46427179/article/details/109881136