`
ihyperwin
  • 浏览: 434628 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java方法覆盖的原则

 
阅读更多
什么是方法覆盖

如果在子类中定义的一个方法,其名称、返回类型及参数签名正好与父类中某个方法的名称、返回类型及参数签名相匹配,那么可以说,子类的方法覆盖了父类的方法。

覆盖方法必须满足的十大约束

一:子类方法的名称、参数签名和返回类型必须与父类方法的名称、参数签名和返回类型一致


二:子类方法不能缩小父类方法的访问权限


三:子类方法不能抛出比父类方法更多的异常,子类方法抛出的异常必须和父类方法抛出的异常相同,或者子类方法抛出的异常类是父类方法抛出的异常类的子类


四:方法覆盖只存在于子类和父类(包括直接父类和间接父类)之间。在同一个类中方法只能被重载,不能被覆盖。

五:父类的静态方法不能被子类覆盖为非静态方法。
(子类的非静态方法不能覆盖父类的静态方法)


六:子类可以定义与父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。


子类隐藏父类的静态方法和子类覆盖父类的实例方法,这两者的区别在于:运行时,Java虚拟机把静态方法和所属的类绑定,而把实例方法和所属的实例绑定。
  
看个SCJP题库的经典例子吧,并说说为什么是这样的结果

代码:
class Base {
     void method() {
         System.out.println("method of Base");
     }
     static void staticMethod() {
         System.out.println("static method of Base");
     }
}

class Sub extends Base {
     void method() {
         System.out.println("method of Sub");
     }
     static void staticMethod() {
         System.out.println("static method of Sub");
     }
}

public class Test2 {
     public static void main(String[] args) {
         Base sub1 = new Sub();
         sub1.method();
         sub1.staticMethod();
         Sub sub2 = new Sub();
         sub2.method();
         sub2.staticMethod();
     }
}
答案:
method of Sub
static method of Base
method of Sub
static method of Sub

七:父类的非静态方法不能被子类覆盖为静态方法。
(父类的非静态方法不能被子类的静态方法所覆盖)


八:父类的私有方法不能被子类覆盖。
同第六点一样,再来个经典的SCJP题目

class Base {
private String showMe() {
return "Base";
}

public void print(){
System.out.println(showMe());
showMe();
}
}

public class Sub extends Base {
public String showMe(){
return "Sub";
}
}
   public static void main(String args[]){

   Sub sub=new Sub();

   sub.print();
   }
}



九:父类的抽象方法可以被子类通过两种途径覆盖:一是子类实现父类的抽象方法;二是子类重新声明父类的抽象方法。

十:父类的非抽象方法可以被覆盖为抽象方法。



另外,关于构造函数:

子类的实例化过程:子类中所有的构造函数会去访问父类中的空参数构造函数,那是因为每一个子类构造函数中的第一行都有一句隐式super语句。

构造函数不能继承。
子类的构造函数可以通过super关键字显式调用父类中的构造函数。如果子类中的构造函数没有显式调用父类中的构造函数,编译器就会自动在子类的构造函数中调用父类中参数为空的构造函数。于是,当父类中没有参数为空的构造函数,而子类中又没有显示调用父类的其他构造函数,编译时就会报错。这一点需要特别注意。当父类中没有定义任何构造函数时,编译器就会为它指定一个参数为空的默认的构造函数;如果父类中定义了构造函数,那么编译器就不会为它指定一个参数为空的默认构造函数了。因此,如果某个类有可能成为其他类的父类,为了避免发生不必要的编译错误,最好为它编写一个参数为空的构造函数。

eg1.
父类Sup中没有定义构造函数,编译程序将为它指定一个参数为空的默认构造函数。子类Sub中也没有定义构造函数,编译程序也会为它指定一个参数为空的默认的构造函数,并且会在这个默认的构造函数中调用父类的参数为空的构造函数。
public class Sub extends Sup{
    //子类中没有定义构造函数
    public static void main(String args[]){
        Sub sub=new Sub();
    }
}

class Sup{
    //父类中没有定义构造函数
}


eg2.
父类Sup中没有定义构造函数,编译程序将为它指定一个参数为空的默认构造函数。子类定义了一个带整型参数的构造函数,在这个构造函数中子类没有显式调用父类的构造函数,所以编译器为在它里面调用父类中参数为空的构造函数。

public class Sub extends Sup{
    //子类中定义类一个带整型变量参数的构造函数
    public Sub(int i){
        //
    }
    public static void main(String args[]){
        Sub sub=new Sub(1);
    }
}
class Sup{
    //父类中没有定义构造函数
}
eg3.
父类中定义了一个带整型参数的构造函数,因此编译器不再为它指定参数为空的默认的构造函数。子类中也定义了一个带整型参数的构造函数。编译时,编译器将试图在子类的构造函数中调用父类的参数为空的构造函数,但是父类中没有定义参数为空的构造函数,所以编译程序将会报错。排错的方法时在子类的构造函数中显示调用父类的构造函数,或者在父类中添加一个带空参数的构造函数。

public class Sub extends Sup{
    //子类中定义类一个带整型变量参数的构造函数
    public Sub(int i){
        //
    }
    public static void main(String args[]){
        Sub sub=new Sub(1);
    }
}

class Sup{
    //父类中定义了一个带整型参数的构造函数
    public Sup(int i){
        //
    }
}
 

排错方法1:

public class Sub extends Sup{
    //子类中定义类一个带整型变量参数的构造函数
    public Sub(int i){
        super(i);//调用父类中的构造函数
    }
    public static void main(String args[]){
        Sub sub=new Sub(1);
    }
}

class Sup{
    //父类中定义了一个带整型参数的构造函数
    public Sup(int i){
        //
    }
}
 
排错方法2:

public class Sub extends Sup{
    //子类中定义类一个带整型变量参数的构造函数
    public Sub(int i){
        //
    }
    public static void main(String args[]){
        Sub sub=new Sub(1);
    }
}

class Sup{
    //父类中定义了一个带整型参数的构造函数
    public Sup(int i){
        //
    }
    //定义一个带空参数的构造函数
    public Sup(){
        //
    }
}
分享到:
评论

相关推荐

    Java新手指南方法覆盖Java开发Java经验技巧共14

    在Java编程语言中,"方法覆盖"(Method Overriding)是一个重要的面向对象特性,它允许子类重写父类中的方法。本指南旨在帮助新手理解这一概念,掌握Java开发中的关键技巧,提升编程能力。这份14页的PDF文档可能涵盖...

    Java方法继承、方法重载、方法覆盖小结.doc

    Java 方法继承、方法重载、方法覆盖、小结 Java 编程语言中,方法继承、方法重载、方法覆盖是三个重要的概念,它们在软件开发中发挥着重要作用。 方法继承 方法继承是 Java 编程语言的一种机制,允许一个类继承另...

    Java 实例 - 方法覆盖源代码-详细教程.zip

    首先,方法覆盖遵循“向上转型”原则,即当我们有一个父类引用指向子类对象时,如果子类重写了父类的方法,那么通过父类引用调用该方法时,执行的是子类的方法实现。这是多态性的一种体现,增强了程序的灵活性。 1....

    java的里氏代换原则

    Java 编译器在编译时会检查代码是否遵循里氏代换原则,不允许子类覆盖父类中的私有方法,以保证子类实例在所有情况下都能代替父类实例。此外,Java 8 引入了默认方法(default methods)进一步增强了接口的灵活性,...

    JAVA架构设计原则与J2EE必读书目推荐

    ### JAVA架构设计原则 #### 基本原则 在探讨JAVA架构设计时,有几个核心原则是必不可少的: 1. **分层原则**:这一原则强调通过分层来降低软件的复杂性。它将整个系统划分为不同的逻辑层级,每一层都承担特定的...

    java中方法的继承,覆盖.doc

    在Java编程语言中,方法的继承和覆盖是面向对象特性的重要组成部分,它们允许子类扩展或修改父类的行为。以下是对这些概念的详细说明: **方法的继承:** 当一个类(子类)继承另一个类(父类)时,子类会自动获得...

    java设计原则16种:总结完整版(PDF)

    如果`Rectangle`类覆盖了`setWidth`和`setHeight`方法,并且这些方法改变了`area()`的计算结果,那么就违反了里氏替换原则。 **实现方式**:确保子类在扩展父类功能的同时,不改变父类原有方法的预期行为。 --- #...

    JAVA设计模式的六大原则

    ### JAVA设计模式的六大原则 #### 一、开闭原则(Open-Close Principle) **定义:** 开闭原则强调的是软件实体(类、模块、函数等)应该是可扩展的但不可修改的,即软件实体应该对扩展开放,对修改关闭。 **实践...

    里氏替换原则Demo

    但是,如果`Animal`类有一个`eat()`方法,定义为吃草,而`Dog`类覆盖了这个方法,让它吃肉,这就违反了LSP。因为不是所有的`Animal`都吃草,`Dog`作为`Animal`的子类,它的行为与基类不符,这将可能导致程序出错。 ...

    java-jacoco-单元测试覆盖-示例项目

    1. **代码覆盖率统计**:JaCoCo能够统计Java应用的执行路径,提供行覆盖率、分支覆盖率、方法覆盖率等多种覆盖率指标。 2. **实时反馈**:JaCoCo支持集成到IDE如IntelliJ IDEA和Eclipse中,开发者可以实时查看当前...

    Java并发编程:设计原则与模式2中文版

    总的来说,《Java并发编程:设计原则与模式2中文版》是一本全面覆盖Java并发编程的指南,它不仅包含了理论知识,还有大量实战经验分享。通过阅读本书,开发者可以提升对Java并发的理解,学会如何设计和实现高性能、...

    计算机软件开发的Java编程语言及应用——评《Java编程方法论》.pdf

    【Java编程语言特点】 Java编程语言是面向对象的...《Java编程方法论》这本书的详细内容,无疑为Java学习者和开发人员提供了宝贵的理论指导和实践案例,有助于他们深入理解和熟练运用Java,提升软件开发的效率和质量。

    Java复习题及答案

    4. `Applet`子类通常覆盖`init()`方法以初始化界面。 5. 数据会被写入到文件,字节数取决于写入的具体数据。 这些题目涵盖了Java的核心概念,如类、接口、构造器、包管理、异常处理、方法重载、对象初始化、事件...

    JAVA 面试 1000题内容全覆盖2017年新版

    本书《JAVA 面试 1000题内容全覆盖2017年新版》是一本为Java面试准备的题目集,提供了详尽的解答,覆盖了各类面试可能出现的问题,是准备面试和考试的参考书。 首先,书中会对Java的基础知识进行提问和解答,比如:...

    Java 实现继承实例代码

    这是因为Java遵循多态性原则,即子类对象可以被视为父类对象,但其行为可以体现出子类的特性。 ```java public class Main { public static void main(String[] args) { Child child = new Child(); child....

    JAVA的重载和覆盖(论文)

    JAVA中的重载(Overload)和覆盖(Override)是面向对象编程中两个核心概念,尤其在多态性的体现上扮演着重要角色。这两者虽然在名称上相似,但在实际应用和概念理解上有着本质的区别。 ### 重载(Overload) 重载是在同...

    覆盖广的JAVA WEB机试

    在这个“覆盖广的JAVA WEB机试”中,考生可能会遇到多种关键概念和实践,下面将对这些可能涉及的知识点进行详细的阐述。 1. **Servlet与JSP**:Servlet是Java Web应用的核心,它提供了服务器端处理HTTP请求的能力。...

    Java面向对象设计原则.docx

    LSP原则与单一职责原则和接口分离原则密切相关,如果一个类比子类具备更多功能,很有可能某个功能被子类覆盖。 遵循这些设计原则,可以帮助Java程序员编写更加灵活、可维护、可扩展的代码,提高开发效率和代码质量...

    java笔记 java笔记

    - **父类与子类的关系**:子类继承父类的属性和方法,并可添加新的方法或覆盖已有的方法。 - **构造对象的顺序**:首先构造父类对象,然后构造子类对象。 ##### 7.3 多态 多态允许子类对象被当作父类对象来处理,...

Global site tag (gtag.js) - Google Analytics