java 多态的应用_java中的多态关系的运用

本文详细介绍了Java中的多态性概念,包括其发生的三个条件:继承、重写和父类引用指向子类对象。通过示例代码展示了多态调用方法的规则,以及如何通过super关键字调用父类被重写的方法。多态的好处在于提供良好的扩展性和通用处理能力。文章还通过两个实例深入探讨了多态的执行顺序和构造函数的调用规则,以及静态和动态成员的初始化顺序。
摘要由CSDN通过智能技术生成

1、多态发生的三个必备条件

继承、重写、父类引用指向子类对象

2、注意

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

方法的重写,也就是子类能够重写父类的方法

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。要想调用父类中被重写的方法,则必须使用关键字super。

3、好处

可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

4、例子

1 //父类

2 packagecom.test.five;3

4 public classParent {5 public voidTest(){6 System.out.println("我 是 父类");7 }8 }9

10 //子类一

11 packagecom.test.five;12

13 public class Child extendsParent {14 public voidTest(){15 System.out.println("我 是大儿子");16 }17 public voidSex(){18 System.out.println("我 是个男的");19 }20 }21 //子类二

22 packagecom.test.five;23

24 public class Sister extendsParent{25 public voidTest(){26 System.out.println("我也是个子类");27 }28 public voidSex(){29 System.out.println("我是个女儿");30 }31 }32 //测试类

33 packagecom.test.five;34

35 public classTest {36 public static voidmain(String[] args) {37 Parent p = newChild();38 p.Test();//父类声明,子类创建,调用该对象的方法(子类父同时所拥有的方法)39 Show(p);40 Show(newSister());41 Show(newChild());42 }43 //测试类中的静态类方法,在测试类中可以直接调用此方法(不用再实例化类的对象)

44 public static voidShow(Parent p){45 p.Test();46 if( p instanceofChild){47 Child c =(Child)p;48 c.Sex();49 }else if(p instanceofSister){50 Sister s =(Sister)p;51 s.Sex();52 }53 }54 }

得出的结果是:

我 是大儿子

我 是大儿子

我 是个男的

我也是个子类

我是个女儿

我 是大儿子

我 是个男的

5、注意(例子)

1 //父类

2 packagecom.test.six;3

4 public classEmploee {5 privateString name;6 privateString address;7 private intnum;8 public Emploee(String name,String address,intnum){9 System.out.println("Emploee的构造函数");10 this.name =name;11 this.address =address;12 this.num =num;13 }14 public voidcheck(){15 System.out.println("Emploee中check的name:"+this.name+" ,address = "+this.address);16 }17 publicString toString(){18 return name+" "+address+" "+num;19 }20 publicString getName() {21 returnname;22 }23 public voidsetName(String name) {24 this.name =name;25 }26 publicString getAddress() {27 returnaddress;28 }29 public voidsetAddress(String address) {30 this.address =address;31 }32 public intgetNum() {33 returnnum;34 }35 }36

37 //子类

38 packagecom.test.six;39

40 public class Salary extendsEmploee {41 private doublesalary;42 //构造函数

43 public Salary(String name, String address, int num,doublesalary) {44 super(name, address, num);45 System.out.println("salary的构造函数");46 setSalary(salary);47 }48 public doublegetSalary() {49 returnsalary;50 }51

52 public void setSalary(doublesalary) {53 if(salary >=0.0){54 this.salary =salary;55 }56 }57 public voidcheck(){58 System.out.println("这是salary的check的方法");59 System.out.println("Salary中的name="+getName()+" 薪资="+getSalary());60 }61 public doublecomputePay() {62 System.out.println("计算工资,付给:" +getName());63 return salary/52;64 }65 }66 //测试类

67 packagecom.test.six;68

69 public classTest {70 public static voidmain(String[] args) {71 Salary s = new Salary("张三", "北京", 3, 8000.0);72 Emploee e = new Salary("李四", "上海", 5, 10000.0);73 System.out.println("salary对象引用中的方法调用");74 s.check();75 s.computePay();76 System.out.println("emploee对象引用中的方法调用");77 e.check();78 }79 }

得到的结果如下:

1 Emploee的构造函数2 salary的构造函数3 Emploee的构造函数4 salary的构造函数5 salary对象引用中的方法调用6 这是salary的check的方法7 Salary中的name=张三 薪资=8000.0

8 计算工资,付给:张三9 emploee对象引用中的方法调用10 这是salary的check的方法11 Salary中的name=李四 薪资=10000.0

----一旦实例化一个对象,其执行顺序,首先:

在不涉及继承的前提下,当首次加载类时,按照如下顺序执行:

1、按照出现顺序先后执行静态成员变量定义与静态块;

2、按照出现顺序先后执行动态成员变量定义与动态块;

3、执行构造函数;

4、再次实例化对象时只执行第2、4步即可;

在涉及到继承时,按照如下顺序执行:

1、执行父类的静态成员变量定义与静态块,执行子类的静态成员变量与静态块

2、执行父类非静态成员变量定义与动态块,执行父类构造方法;

3、执行子类的非静态成员变量定义与动态块,执行子类构造方法;

注意:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在

调用父类构造函数中使用子类重写的方法。

例子一:

packagecom.test.seven;public classTestOne {private static TestOne t1 = newTestOne();//静态变量

private static inti1;private static int i2 = 2;

publicTestOne(){

i1++;

i2++;

}public static voidmain(String[] args) {

TestOne t2= newTestOne();

System.out.println("t2.i1 = " +t2.i1);

System.out.println("t2.i2 = "+t2.i2);

}

}

得到的结果如下:

t2.i1 = 2

t2.i2 = 3

执行过程:

首先执行给t1、i1、i2分别给予初始值null,0,0,在执行TestOne t1 = new TestOne();

这样子i1++,i2++被执行,i1,i2都变成1,执行完毕后接着执行int i1 ,i1,i2的值仍然是1,1,当执行int i2=2时,i2被赋予了值,即i1=1,i2=2;再执行

TestOne t2 = new TestOne(),i1,i2在执行++,此时i1=2,i2=3,输出i1,i2,结果就是:t2.i1=2,t2.i2=3通过上面代码可以知道:

系统默认的给予比通过等号的赋予先执行。

例子二:

packagecom.test.seven;public classTestOne {private static TestOne t1 = newTestOne();//静态变量

private static inti1;private static int i2 = 2;//静态块

static{

System.out.println("静态块");

}//动态块

{

System.out.println("动态块");

}publicTestOne(){

i1++;

System.out.println("i1--------------"+i1);

i2++;

System.out.println("i2--------------"+i2);

}public static voidmain(String[] args) {

TestOne t2= newTestOne();

System.out.println("t2.i1 = " +t2.i1);

System.out.println("t2.i2 = "+t2.i2);

}

}

得到的结果如下:

1 动态块2 i1--------------1

3 i2--------------1

4 静态块5 动态块6 i1--------------2

7 i2--------------3

8 t2.i1 = 2

9 t2.i2 = 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值