基于继承的多态实现

多态:一个名字可以表示许多不同类(这些不同类必须拥有一个共同的超类)的对象,从而实现以不同的方式来响应某个共同的操作集。

在java中,名字指的就是变量名,我们可以认为每个对象都有一个名字---引用该对象的变量名。比如String str = "abcd";我们就称之为对象str。因此,在java中的多态就体现在一个变量可以引用多个不同类对象,前提是这些不同类必须有者共同的父类,从而该变量可以且只能调用每个不同对象之间的公共操作集(方法)。

很明显,多态的实现是基于继承的。比如,前面所说的Manager类继承了父类Employee的所有属性和方法,这就是说,任何在Employee上的合法操作在Manager上也合法!

一个变量只能有一个类型!这个类型是在编译时指定的,按照多态的定义,一个变量可以指向不同类型的对象,在java中,当这个条件成立时,那这个变量就是多态性的!我们先来看看java中多态的实现。

父类变量可以引用子类对象!这在java是允许的,即Employee e  = new Manager()是合法的,但是请注意,变量e只能调用共同的成员属性与方法,即e只能访问子类从父类中继承过来的成员!

//error! 父类变量不能访问属于子类特有的成员(即非公有成员)

e.dept = "";

以上只是实现了多态的一部分:一个父类变量引用许多不同子类对象。

接着,我们再来分析以下例题:

class Engineer extends Employee {
	public String getEmpDetails() {
		return "Engineer getEmpDetails()";
	}
}

class Manager extends Employee {
	public String getEmpDetails() {
		return "Manager getEmpDetails()";
	}

	public void m1() {
	}
}

通过以上定义,我们已知类Engineer和类Manager分别继承了类Employee,并且都覆盖了从父类中继承过来的方法getEmpDetails(),在main方法中执行以下代码:

1  Employee e = new Manager();

2  System.out.println(e.getEmpDetails());

3  e = new Engineer();

4  System.out.println(e.getEmpDetails());

结果是执行语句2打印:"Engineer getEmpDetails()",执行语句4打印:"Manager getEmpDetails()"。

分析:首先,通过语句1和3可以得知父类变量e可以引用不同类型的子类对象,并且,当e引用子类Manager对象时调用方法getEmpDetails()时,返回的是子类Manager已覆盖的方法内容,因此,现在我们可以肯定一点,当子类覆盖父类方法时,子类对象访问的将是已被覆盖的内容!

其次,通过语句2和4的执行结果对比,父类变量引用子类对象时,调用的将是每一个被引用对象的成员方法,即引用不同的子类对象则调用该子类的成员方法,互不干扰!

如果增加以下语句:e.m1();

将会是编译错误,因为该父类变量调用了一个不属于公有的方法,m1()是Manager类的特有成员,而不是从父类继承下来的。Manager的特殊部分是隐藏的。这是因为编译者应意识到,e 是一个Employee,而不是一个Manager

因此,通过以上分析,我们可以得出结论:父类变量可以引用子类对象,同时该父类变量只能访问所有子类的公有操作集(从父类继承过来的成员);当子类中已覆盖继承方法时,父类变量调用的将是子类中的已覆盖方法!

可以创建具有共同类的对象的收集(如数组)。这种收集被称作同类收集。

就是因为有了java的这种多态机制,我们因而可以实现异类收集!java拥有一个顶层父类java.lang.Object,该类是所有类的顶级父类,在我们平常定义各种类时,虚拟机会自动在类的声明语句后加上继承Object类,如下:

class Employee 与 class Employee extends Object是等同的!extends Object是JVM自动给任意类加上去的,从而保证java中的所有类都具备一个通用父类。

既然Object是所有类的父类,那么我们就可以通过Object数组来实现异类收集,由于多态性,Object数组就能收集所有种类的元素,如:

Object[] obj = {"123", new Employee(), new Manager()}; //收集了三种不同类型对象

Employee[] e = {new Employee(), new Manager(), new Engineer()};  //收集了三种不同子类对象

可以分解为: e[0] = new Employee();

    e[1] = new Manager();

    e[2] = new Engineer();

以上语句恰好满足了java中的父类变量可以引用子类对象的定义,因此,以上语句都是合法的。

异类收集就是不相同的对象的收集。

Java视频教程 请登录 www.rjpx.net
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在面向对象编程中,多态是指通过不同类型的对象调用相同的方法,可以产生不同的行为。在没有继承的情况下,我们可以使用接口(interface)来实现多态。 接口是一种定义了一组方法签名的抽象类型。一个类可以实现一个或多个接口,然后根据实现的接口来调用相应的方法。通过这种方式,即使没有继承关系,不同的类实现了相同的接口,就可以实现多态。 下面是一个示例: ```java interface Animal { void makeSound(); } class Dog implements Animal { @Override public void makeSound() { System.out.println("Dog barks"); } } class Cat implements Animal { @Override public void makeSound() { System.out.println("Cat meows"); } } public class Main { public static void main(String[] args) { Animal dog = new Dog(); Animal cat = new Cat(); dog.makeSound(); // 输出: Dog barks cat.makeSound(); // 输出: Cat meows } } ``` 在上面的示例中,`Animal` 是一个接口,定义了 `makeSound()` 方法。`Dog` 和 `Cat` 类分别实现了 `Animal` 接口,并实现了自己的 `makeSound()` 方法。在 `Main` 类中,我们创建了一个 `Dog` 对象和一个 `Cat` 对象,并通过它们的共同接口 `Animal` 调用了 `makeSound()` 方法。尽管 `Dog` 和 `Cat` 类没有继承关系,但由于它们都实现了 `Animal` 接口,所以可以使用相同的方式调用 `makeSound()` 方法,实现多态的效果。 这种基于接口的多态性可以让我们在不依赖具体实现类的情况下编写通用的代码,提高代码的灵活性和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值