继承与多态

继承与多态

多态与is-a

在Java中。子类只能继承一个父类,子类与父类之间会有is-a(是一种)的关系。要理解多态要知道自己操作的是哪一种东西。

如下一种继承关系:

image

对象种类:
第一种:

SwordsMan swordsMan = new SwordsMan();
Magician magician = new Magician();

第二种:

Role role1 = new SwordsMan();
Role role2 = new Magician();

第三种:

SwordsMan swordsMan = new Role();
Magician magician = new Role();

要知道以上程序片段为何可以通过编译,为何无法通过编
译,就是将自己当作编译程序,检查语法的逻辑是否正确,方式是从=号右边往左读:右边
是不是一种左边呢(右边类是不是左边类的子类)?

        role si a →
Role role = new SwordsMan();

从右往左读!!
SwordsMan 是一种Role所以正确。同理判断第二种第三种方式。

Role不一定是一种SwordsMan 编译失败!

  • 编译成功,执行成功
SwordsMan swordsMan = new SwordsMan();
Role role = swordsMan; // SwordsMan 是一种Role
  • 编译失败
SwordsMan swordsMan = new SwordsMan();
Role role = swordsMan; // SwordsMan 是一种Role,这行通过编译
SwordsMan swordsMan = role; // Role 不一定是一种SwordsMan,编译失败
  • 编译成功,执行成功
SwordsMan swordsMan = new SwordsMan();
Role role = swordsMan; // SwordsMan 是一种Role,这行通过编译
// 你告诉编译程序要让Role 扮演SwordsMan,以下这行通过编译
SwordsMan swordsMan = (SwordsMan) role; // role 参考SwordsMan 实例,执行成功
  • 编译成功,执行报错ClassCastException:
SwordsMan swordsMan = new SwordsMan();
Role role = swordsMan; // SwordsMan 是一种Role,这行通过编译
// 你告诉编译程序要让Role 扮演Magician,以下这行通过编译
Magician magician = (Magician) role; // role 参考Magician 实例,执行失败

多态

设定两个类都有血量输出:想输入血量代码如下

public static void showBlood(SwordsMan swordsMan) {
System.out.printf("%s 血量 %d%n",
swordsMan.getName(), swordsMan.getBlood());
}
public static void showBlood(Magician magician) {
System.out.printf("%s 血量 %d%n",
magician.getName(), magician.getBlood());
}

分别为SwordsMan 与Magician 设计showBlood()同名方法,这是重载方法的运用,如此
就可以如下调用:
···
showBlood(swordsMan); // swordsMan 是SwordsMan 类型
showBlood(magician); // magician 是Magician 类型
···

问题:目前只有SwordsMan 与Magician 两个角色,如果有100
个角色呢?重载出100 个方法?这种方式显然不可能。

解决办法:

package cc.openhome;
public class RPG {
public static void showBlood(Role role) {
System.out.printf("%s 血量 %d%n",
role.getName(), role.getBlood());
}
public static void main(String[] args) {
SwordsMan swordsMan = new SwordsMan();
swordsMan.setName("Justin");
swordsMan.setLevel(1);
swordsMan.setBlood(200);
Magician magician = new Magician();
magician.setName("Monica");
magician.setLevel(1);
magician.setBlood(100);
showBlood(swordsMan);
showBlood(magician);
}
}

在这里仅定义了一个showBlood()方法,参数声明为Role 类型。第一次调用showBlood()
时传入了SwordsMan 实例,这是合法的语法,因为SwordsMan 是一种Role。第一次调用
showBlood()时传入了Magician 实例也是可行,因为Magician 是一种Role 。执行的结果如下:

Justin 血量 200
Monica 血量 100

这样的写法好处为何?就算有100 种角色,只要它们都是继承Role,都可以使用这个
方法显示角色的血量,而不需要像前面重载的方式,为不同角色写100 个方法,多态的写
法显然具有更高的可维护性。

构造函数

如果类有继承关系,在创建子类实例后,会先进行父类定义的初始流程,再进行子类
中定义的初始流程,也就是创建子类实例后,会先执行父类构造函数定义的流程,再执行
子类构造函数定义的流程。
构造函数可以重载,父类中可重载多个构造函数,如果子类构造函数中没有指定执行
父类中哪个构造函数,默认会调用父类中无参数构造函数。如果这样撰写程序:

class Some {
Some() {
System.out.println("调用Some()");
}
}


class Other extends Some {
Other() {
System.out.println("调用Other()");
}
}

如果尝试new Other(),先执行Some()中的流程,再执行Other()中的流程,
也就是先显示”调用Some()”,再显示”调用Other()”。很奇怪是吧!先继续往下看,就知道
为什么了。如果想执行父类中某构造函数,可以使用super()指定。例如:

class Some {
Some() {
System.out.println("调用Some()");
}
Some(int i) {
System.out.println("调用Some(int i)");
}
}
class Other extends Some {
Other() {
super(10);
System.out.println("调用Other()");
}
}

执行结果:
调用Some10
调用Other

在这个例子中,new Other()时,先调用了Other()版本的构造函数,super(10)表示调用
父类构造函数时传入int 数值10,因此就是调用了父类中Some(int i)版本的构造函数,而
后再继续Other()中super(10)之后的流程。

注意:,编译程序会在你没有撰写任何构造函数时,自动加入没有参数的默认构
造函数(Default constructor),如果自行定义了构造函数,就不会自动加入任何构造函数了。Other
的构造函数中没有指定调用父类中哪个构造函数,而且父类中还没有无参构造函数会编译失败。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的继承是面向对象编程中的一种重要概念,通过继承可以实现类与类之间的父子关系,子类可以继承父类的属性和方法。在继承关系中,子类可以对父类的方法进行重载和覆盖,从而实现多态的概念。 通过继承,子类可以继承父类的非私有成员变量和方法。这样可以实现代码的复用,避免重复编写相似的代码。通过继承,可以在子类中调用父类的方法,也可以在子类中新增自己特有的方法和属性。子类还可以对从父类继承来的方法进行修改,以适应自己的需求。 多态是指同一类型的对象,在不同的状态下表现出不同的行为。在Java中,多态性可以通过继承和方法的重写实现。当父类的引用指向子类的实例时,可以通过该引用调用子类中重写的方法,实现不同类的对象调用同一个方法产生不同的结果。多态可以提高代码的灵活性和扩展性,使得程序更易于维护和扩展。 在Educoder平台上,可以通过练习和编程任务来学习和掌握Java继承多态。通过编写继承父类的子类,重写父类的方法以及引用父类的实例来实现多态,可以更好地理解和应用这两个概念。平台提供了丰富的练习题和编程任务,帮助学习者提高对继承多态的理解和应用能力。 总之,Java中的继承多态是面向对象编程中的重要概念,通过继承可以实现代码的复用,多态可以实现不同对象的不同行为。在Educoder平台上通过练习和编程任务,可以更好地学习和掌握这两个概念。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值