`
thinkingmt
  • 浏览: 24701 次
  • 性别: Icon_minigender_1
  • 来自: 桂林
社区版块
存档分类
最新评论

子类到底继承了什么?(A)

 
阅读更多

Java的继承可以在结构和功能上为程序带来很好的便捷性和灵活性。但是在继承的过程中,如果不能够非常深刻的理解这其中的一些规律规则,就不能够很好的发挥继承带来的优势,甚至会造成一些错误。

 

继承和abstract

 

 

 

 

 

这三个类的代码如下:

 

import java.awt.event.*;

public abstract class grandfather implements ActionListener
{
    public abstract void m1();
}



import java.awt.event.*;

public abstract class father extends grandfather
{
    public abstract void  m2();
}



import java.awt.event.*;

public class son extends father
{
    public void m1()
    {}

    public void m2()
    {}
    
    public void actionPerformed(ActionEvent e)
    {}
}

 

 

在这个程序中,最原始的基类---grandfather,是一个抽象类,它有一个m1()的抽象方法。此外,grandfather还实现了ActionListener接口,按理说是需要重写接口中的actionPerformed()方法的,但由于grandfather本身是一个抽象类,就可以不覆盖actionPerformed()。(若将grandfather又抽象类改为普通类,编译将无法通过,编译器会提示:grandfather不是抽象的,并且未覆盖XXX中的抽象方法XXX(parameters)  )。

 

按照继承的规则,其子类---father,在继承grandfather之后,需要对m1()进行重写(overriding),但碰巧的是,father自身有一个抽象方法m2(),所以father也必须也声明为一个抽象类(否则无法通过编译),这个时候,由于father是抽象类,就可以不去覆盖其基类的抽象方法了。

 

最后一个类,father的子类---son,是一个普通的非抽象的类,这时候,由于son不抽象,就无法逃过重写的责任了,它必须将其基类father的抽象方法m2()进行重写,不仅如此,由于其基类father未重写最原始基类grandfather的抽象方法m1()和actionPerformed(),son还需要重写这两个方法。否则会编译器无法通过编译。

 

也就是说,一个抽象方法最终一定会得到重写,就算第一个子类将自身定义为抽象类,逃掉了重写的责任,以后也必然会有一个非抽象的子类来完成早该完成的重写任务。当然,如果所有类都是抽象的,抽象方法就可以一直不去重写,不过这显然是不可能,也是没有意义的。

 

在这个程序中,我认为每个类都应该定义好自己的行为,及时的重写自己该重写的方法,这样,既可以避免许多编译无法通过的麻烦,也可以提高类的内聚性,使一个类的更加凸显出自己的作用与功能(比如说grandfather实现ActionListener的接口,肯定是需要对component进行监听,那么actionPerformed()方法理应在grandf里就实现,而不该拖到son类中实现),同时还必然为子类减轻了负担。

 

更加合理的代码如下:

 

import java.awt.event.*;

public abstract class grandfather implements ActionListener
{
    public abstract void m1();
    
    public void actionPerformed(ActionEvent e)
    {}
}



import java.awt.event.*;

public abstract class father extends grandfather
{
    public abstract void  m2();
    
    public void m1(){};
    
    //public void actionPerformed(ActionEvent e)
    //{}
}



import java.awt.event.*;

public class son extends father
{
    public void m2()
    {}
    
    //public void m1()
    //{}
    
    //public void actionPerformed(ActionEvent e)
    //{}
}



 

 

此时father和son中的被注释掉的代码,视具体情况选择需不需要,father中的m1()和son中的m1(),m2(),和actionPerformed()就不仅仅为通过编译了,而是为了通过overriding与inheritance为类自身提高性能和功能,从而提高程序的效率。

分享到:
评论
2 楼 thinkingmt 2012-05-09  
引用
一个抽象方法最终一定会得到重写,就算第一个子类将自身定义为抽象类,逃掉了重写的责任,以后也必然会有一个非抽象的子类来完成早该完成的重写任务。


其实Java这样做也不难理解:作为一个抽象类,其本身是不可以被实例化的,所以就算有某些抽象方法没有实现或重写也无碍,反正在程序运行时这些方法不会被真正地调用(就算调用,也是跑到子类去调用被实现了的重写方法了。),但是我个人觉得抽象类应该是因为自身有抽象方法才把自己定义为抽象类的,而不能因为自身继承了其他类的抽象方法,为了不去重写而将自身抽象。
相反,作为非抽象类,如果类中存在有未实现的方法的话,无论是继承而来的,还是自身定义的,都是不被允许的,因为类本身是不抽象的,如果这个类被实例化后并且调用了那些没有实现的方法,效果相当于是空,因为调用的是抽象的方法,不能做任何事情,这也是为什么非抽象类必须重写基类抽象方法的原因吧!
1 楼 thinkingmt 2011-12-16  
以下段落和我的见解是一样的,分享过来:

……………………………………………………………………………………………………………

In the section on Interfaces, it was noted that a class that implements an interface must implement all of the interface's methods. It is possible, however, to define a class that does not implement all of the interface methods, provided that the class is declared to be abstract. For example,

abstract class X implements Y {
  // implements all but one method of Y
}

class XX extends X {
  // implements the remaining method in Y
}
In this case, class X must be abstract because it does not fully implement Y, but class XX does, in fact, implement Y.

……………………………………………………………………………………………………………

来自:THE JAVA TUTORIAL:Abstract Methods and Class. URL:http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

相关推荐

    10丨理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?1

    继承表达了“is-a”关系,即子类是父类的一种特殊类型。然而,过度依赖继承会导致一系列问题: 1. **继承层次过深**:当继承链变得很长时,理解一个类的行为需要查看整个继承树,这对代码的阅读和理解造成困难。 2....

    第十二天 04单继承:子类只继承一个父类【千锋Python人工智能学院】1

    在Python编程语言中,继承是面向对象编程的一个核心特性,它允许子类(派生类)从父类(基类)那里获得属性和方法,从而实现代码的复用和扩展。这里我们将深入探讨单继承、多继承以及多层继承的概念、语法以及相关...

    继承与接口的含义以及其子类相关的含义

    继承是类之间的一种关系,子类继承自父类,从而获取了父类的部分特性。这种关系模拟了现实世界中的遗传关系,使得子类可以重用和扩展父类的属性和方法。Java中的继承是单继承的,也就是说一个子类只能有一个直接父类...

    C#什么是继承?如何实现继承?

    #### 一、什么是继承? 在面向对象编程中,继承是一种机制,允许程序员定义一个类(称为子类或派生类)来继承另一个类(称为父类或基类)的属性和方法。通过继承,子类不仅可以重用父类的功能,还可以根据需要添加...

    第三章 继承与多态 掌握封装的含义及用法 什么是继承? 继承有什么作用? 怎么写继承?

    **方法的重写(Overriding)** 是指子类继承父类后,可以重新定义父类的方法。子类重写父类的方法时,必须遵循以下规则: 1. 方法名、参数列表和返回类型必须完全一致。 2. 子类方法的访问级别不能小于父类方法的...

    Java继承习题

    - 子类继承父类时,默认只能继承公有(`public`)和受保护(`protected`)的成员,而不能继承私有(`private`)成员。因此,正确答案是 **C. 子类可以继承父类的公有的属性和方法**。 8. **继承声明** - **题目**: 现有...

    将子类引用赋给父类对象时,java虚拟主机并没有将那些非继承成员丢弃

    当一个类B继承自另一个类A,B称为子类,A称为父类。子类B不仅可以继承父类A的所有公有(public)和受保护(protected)成员,还可以有自己的特有成员。当我们声明一个父类类型的引用并将其赋值为子类的对象时,如`...

    Java语言程序设计:JAVA_5-子类与继承.ppt

    1. 子类继承了父类的所有非私有属性和方法,但不能继承带有`private`修饰符的属性和方法,因为`private`是类内可见。 2. 构造函数不能被继承,但子类可以通过`super()`关键字调用父类的构造器来初始化父类的部分。 3...

    子类、父类查询

    有关子类和父类。A是子类,Teacher是父类。A是Teacher 的一种(子类)会继承父类李非私

    java继承例题

    在继承关系中,子类继承了超类的所有成员变量和成员方法,但是子类可以对超类的成员变量和成员方法进行覆盖或重写。 Java继承的特点: 1. 单继承:Java只支持单继承,即一个类只能继承一个超类。 2. 多层继承:...

    多重继承(6_7钻石继承问题)_C++_

    在C++编程语言中,多重继承是一个特性,允许一个类(子类)继承自多个基类(父类)。这种设计模式使得子类可以同时获得多个基类的特性,增加了代码的复用性。然而,多重继承也带来了一些复杂性和潜在的问题,其中最...

    day1继承.md

    Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性...

    27_Java为什么没有多继承

    继承是一种“is-a”关系,允许一个类(子类)继承另一个类(父类)的属性和方法。在支持多继承的语言中,一个类可以同时继承多个父类,这样可以获得多个父类的特性。然而,Java选择了单继承,即一个类只能有一个父类...

    父类引用指向子类对象

    在面向对象编程语言中,子类继承自父类时会自动拥有父类的所有非私有成员(包括属性和方法)。这意味着子类可以被视为是父类的一种特殊形式,即“子类是一种特殊的父类”。因此,可以通过父类的引用变量来操作子类...

    c#中类的继承

    在面向对象编程语言中,继承是一种非常重要的概念,它允许我们定义一个类(称为子类或派生类)来继承另一个类(称为父类或基类)的特性和行为。通过继承,可以有效地复用代码、扩展功能并构建出更为复杂的类结构。本...

    java的继承总结.doc

    继承是特殊的is-a关系,即子类继承父类,说明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。子类和父类之间存在着继承关系,子类继承父类的所有属性和方法。 二、继承的语法格式 Java继承的关键字...

    java三大特性之继承

    面向对象三大特征之继承 ... 如果父类装起来,子类无法直接访问,但是子类确实有继承下来, 可以通过父类提供公共方式进行访问 如果子类编写了有参构造,父类是封装状态,那么有参构造使用s

    C++类继承内存布局详解图(一目了然)

    例如,在单继承中,子类的成员变量和基类的成员变量会被合并到一起。在多重继承中,每个基类的成员变量都会被复制一份。在虚继承中,虚基类的成员变量会被所有派生类共享。 在成员变量和成员函数的访问方面,C++...

Global site tag (gtag.js) - Google Analytics