Java多态和实现接口的类的对象赋值给接口引用的方法(推荐)

2025-05-29 0 89

接口的灵活性就在于“规定一个必须做什么,而不管你如何做”。

我们可以定义一个接口型的引用变量来引用实现接口的实例,当这个引用调用方法时,它会根据实际引用的的实例来判断具体调用哪个方法,这和上述的超对象引用访问子对象的机制相似。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34
//定义接口InterA

interface InterA

{

 void fun();

}

//实现接口InterA的类B

class B implements InterA

{

 public void fun()

 {

  System.out.println(“This is B”);

 }

}

//实现接口InterA的类C

class C implements InterA

{

 public void fun()

 {

  System.out.println(“This is C”);

 }

}

class Test

{

 public static void main(String[] args)

 {

  InterA a;

  a= new B();

  a.fun();

  a = new C();

  a.fun();

 }

}

输出结果为:

?

1

2
This is B

This is C

上例中B和C是实现接口InterA的两个,分别实现了接口的方法fun(),通过将B和C的实例赋给接口引用a,实现了方法在运行时的动态绑定,充分利用了“一个接口,多个方法”,展示了Java的动态多态性。

需要注意的一点是:Java在利用接口变量调用其实现的对象的方法时,该方法必须已经在接口中被声明,而且在接口的实现中该实现方法的型和参数必须与接口中所定义的精确匹配。

——————————————————————————–

扩展

Java运行时多态性:继承和接口的实现

Java是面向对象的语言,而运行时多态性是面向对象程序设计代码重用的一个最强大机制,动态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制,下面就继承和接口实现两方面谈谈java运行时多态性的实现。

一、通过继承中超对象引用变量引用子对象来实现

举例说明:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40
//定义超类superA

class superA {

int i = 100;

void fun() {

System.out.println(“This is superA”);

}

}

//定义superA的子类subB

class subB extends superA {

int m = 1;

void fun() {

System.out.println(“This is subB”);

}

}

//定义superA的子类subC

class subC extends superA {

int n = 1;

void fun() {

System.out.println(“This is subC”);

}

}

class Test {

public static void main(String[] args) {

superA a;

subB b = new subB();

subC c = new subC();

a = b;

a.fun();

(1)

a = c;

a.fun();

(2)

}

}

运行结果为:

?

1

2

3
This is subB

This is subC

上述代码中subB和subC是超superA的子,我们在Test中声明了3个引用变量a, b, c,通过将子对象引用赋值给超对象引用变量来实现动态方法调用。也许有人会问:“为什么(1)和(2)不输出:This is superA”。java 的这种机制遵循一个原则:当超对象引用变量引用子对象时,被引用对象的型而不是引用变量的型决定了调用谁的成员方法,但是这个被调用的方法必须是在超中定义过的,也就是说被子覆盖的方法。

所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,指向了子subB的一个实例,因而(1)所调用的fun()实际上是子subB的成员方法fun(),它覆盖了超superA的成员方法fun();同样(2)调用的是子subC的成员方法fun()。

另外,如果子继承的超是一个抽象,虽然抽象不能通过new操作符实例化,但是可以创建抽象的对象引用指向子对象,以实现运行时多态性。具体的实现方法同上例。

不过,抽象的子必须覆盖实现超中的所有的抽象方法,否则子必须被abstract修饰符修饰,当然也就不能被实例化了。

二、通过接口型变量引用实现接口的对象来实现

接口的灵活性就在于“规定一个必须做什么,而不管你如何做”。我们可以定义一个接口型的引用变量来引用实现接口的实例,当这个引用调用方法时,它会根据实际引用的的实例来判断具体调用哪个方法,这和上述的超对象引用访问子对象的机制相似。

举例说明:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32
//定义接口InterA

interface InterA

{

void fun();

}

//实现接口InterA的类B

class B implements InterA

{

public void fun()

{

System.out.println(“This is B”);

}

}

//实现接口InterA的类C

class C implements InterA

{

public void fun()

{

System.out.println(“This is C”);

}

}

class Test

{

public static void main(String[] args)

{

InterA a;

a= new B();

a.fun();

a = new C();

a.fun();

}

}

输出结果为:

?

1

2

3
This is B

This is C

上例中B和C是实现接口InterA的两个,分别实现了接口的方法fun(),通过将B和C的实例赋给接口引用a而实现了方法在运行时的动态绑定,充分利用了“一个接口,多个方法”展示了Java的动态多态性。

需要注意的一点是:Java在利用接口变量调用其实现的对象的方法时,该方法必须已经在接口中被声明,而且在接口的实现中该实现方法的型和参数必须与接口中所定义的精确匹配。

结束语:以上就是java运行时多态性的实现方法,大家在编程过程中可以灵活运用,但是在性能要求较高的代码中不提倡运用运行时多态,毕竟Java的运行时动态方法调用较之普通的方法调用的系统开销是比较大的。

————————————————–

Java静态方法不具有多态性详解

动态绑定机制使得基的引用能够指向正确的子对象,从而使得面向基编程成为可能。

然而动态绑定在以下两种情况会失效。

1、基方法是private或final修饰的

这个很好理解,因为private说明该方法对子是不可见的,子再写一个同名的方法并不是对父方法进行复写(Override),而是重新生成一个新的方法,也就不存在多态的问题了。同理也可以解释final,因为方法同样是不可覆盖的。

2、方法是static修饰的

代码如下所示.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27
class Base {

public static void staticMethod() {

System.out.println("Base staticMehtod");

}

public void dynamicMehtod() {

System.out.println("Base dynamicMehtod");

}

}

class Sub extends Base {

public static void staticMethod() {

System.out.println("Sub staticMehtod");

}

public void dynamicMehtod() {

System.out.println("Sub dynamicMehtod");

}

}

public class TJ4 {

public static void main(String args[]) {

Base c = new Sub();

c.staticMethod();

c.dynamicMehtod();

}

}

输出结果如下:

?

1

2
Base staticMehtod

Sub dynamicMehtod

输出结果并不像设想的那样,输出 “Sub staticMehtod”。因为静态方法是与而不是与某个对象相关联,c.staticMethod();等同于Car.staticMethod(); 所以尽量不要使用实例变量去调用静态方法,避免混淆。

以上这篇Java多态和实现接口的对象赋值给接口引用的方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java多态和实现接口的类的对象赋值给接口引用的方法(推荐) https://www.kuaiidc.com/118611.html

相关文章

发表评论
暂无评论