`
zy19880423
  • 浏览: 28705 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

Java重写(覆盖)与隐藏

    博客分类:
  • Java
阅读更多

java中方法重写(override)的要求:
1、子类中的方法与父类中的方法的返回类型:

如果返回类型是引用类型,则重写方法的返回类型可以声明为超类方法声明的返回类型的子类型;如果返回类型是基本类型,则重写方法的返回类型必须和超类方法的返回类型相同。  
2、子类中的方法与父类中的方法有相同的方法名称

3、子类中的方法与父类中的方法有相同的参数列表 
4、子类中的方法的访问级别不能低于父类中该方法的访问级别(举例:
   父类方法的级别是protected,那么子类重写该方法,其级别必须是protected或者public,一定和父类的访问级别相同或者更宽,否则编译无法通过) (public>protected>default>private)  
5、子类中方法抛出的异常范围不能大于父类中方法抛出的异常的范围,
      (子类可以不抛出异常也满足该原则,即是说父类抛出异常,子类不抛出异常,编译通过没问题。)

 

例1.class Parent {

      public String publicField = "父类变量";

       public void r(){
        System.out.println("父类函数");
      }
  }

 class Child extends Parent {

     public String publicField = "子类变量";
     public void r(){
        System.out.println("子类函数");
     }

 }
 public static void main(String[] args) {
     Parent subClass = new StringTest().new Child();
     System.out.println(subClass.publicField);
     subClass.r();

 }

//输出:父类变量   子类函数

分析:隐藏字段 :字段不可以被覆盖而只能被隐藏。 

例2 class A{
    private int i;
      A(){
         i=1;
         f();
      } 
    public void f(){
      System.out.println("i="+i);
    }
 }
 class B extends A{
      private int j;
     B(){
          j=1;
      }
     public void f(){
       super.f();
       System.out.println("j="+j);
    }
  }
 public static void main(String[] args){
  StringTest st=new StringTest();
  StringTest.A a=st.new B();
  a.f();//输出i=1   j=0   i=1  j=1

 }

分析:多态new的对象,都是先去到父类中,方法则是在父类中找到最匹配的方法,再看有没被子类覆盖,如有,执行子类方法;如无,执行父类方法,即使子类中存在参数类型最匹配的方法也不会被执行

例3.class Father
{
   int b=6;
  void print()
  {
    System.out.println("Father'b="+b);
  }

}
class Son extends Father
{
   int b=60;
   void print()
  {
    System.out.println("Son'b="+b);
  }
}

Father son=new Son();
System.out.println("b="+son.b);
--结果:b=6.
son.print();
--结果Son'b=60

 分析:隐藏字段 :字段不可以被覆盖而只能被隐藏。   
    

例4.class Father
{
  static void print()
  {
    System.out.println("Father");
  }

}
class Son extends Father
{
   static void print()
  {
    System.out.println("Son");
  }
}

Father f1 = new Fater();
Father f2 = new Son();

f1.print()  //  father
f2.print()  //  father

 

分析:  隐藏静态成员 :类中的静态成员(无论是字段还是方法)不可以被覆盖,只能被隐藏。  


例4.class A {
         public String show(D obj){
                return ("A and D");
         }
         public String show(A obj){
                return ("A and A");
         }
}
class B extends A...{
         public String show(B obj){
                return ("B and B");
         }
         public String show(A obj){
                return ("B and A");
         }
}
class C extends B...{}
class D extends B...{}

问题:以下输出结果是什么?

        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        System.out.println(a1.show(b));   ①
        System.out.println(a1.show(c));   ②
        System.out.println(a1.show(d));   ③
        System.out.println(a2.show(b));   ④
        System.out.println(a2.show(c));   ⑤
        System.out.println(a2.show(d));   ⑥
        System.out.println(b.show(b));     ⑦
        System.out.println(b.show(c));     ⑧
        System.out.println(b.show(d));     ⑨
   

答案   ①   A and A
              ②   A and A
              ③   A and D
              ④   B and A
              ⑤   B and A
              ⑥   A and D
              ⑦   B and B
              ⑧   B and B
              ⑨   A and D


分析:

        ①②③比较好理解,一般不会出错。④⑤就有点糊涂了,为什么输出的不是"B and B”呢?!!先来回顾一下多态性。

        运行时多态性是面向对象程序设计代码重用的一个最强大机制,动态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。

        方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

        当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 (但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了。)

        好了,先温习到这里,言归正传!实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。让我们来看看它是怎么工作的。

        比如④,a2.show(b),a2是一个引用变量,类型为A,则this为a2,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到,于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),this仍然是a2,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为"B and A”。

        再比如⑧,b.show(c),b是一个引用变量,类型为B,则this为b,c是C的一个实例,于是它到类B找show(C obj)方法,没有找到,转而到B的超类A里面找,A里面也没有,因此也转到第三优先级this.show((super)O),this为b,O为C,(super)O即(super)C即B,因此它到B里面找show(B obj)方法,找到了,由于b引用的是类B的一个对象,因此直接锁定到类B的show(B obj),输出为"B and B”。

        按照上面的方法,可以正确得到其他的结果。

        问题还要继续,现在我们再来看上面的分析过程是怎么体现出蓝色字体那句话的内涵的。它说:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。还是拿a2.show(b)来说吧。


        a2是一个引用变量,类型为A,它引用的是B的一个对象,因此这句话的意思是由B来决定调用的是哪个方法。因此应该调用B的show(B obj)从而输出"B and B”才对。但是为什么跟前面的分析得到的结果不相符呢?!问题在于我们不要忽略了蓝色字体的后半部分,那里特别指明:这个被调用的方法必须是在超类中定义过的,也就是被子类覆盖的方法。B里面的show(B obj)在超类A中有定义吗?没有!那就更谈不上被覆盖了。实际上这句话隐藏了一条信息:它仍然是按照方法调用的优先级来确定的。它在类A中找到了show(A obj),如果子类B没有覆盖show(A obj)方法,那么它就调用A的show(A obj)(由于B继承A,虽然没有覆盖这个方法,但从超类A那里继承了这个方法,从某种意义上说,还是由B确定调用的方法,只是方法是在A中实现而已);现在子类B覆盖了show(A obj),因此它最终锁定到B的show(A obj)。这就是那句话的意义所在。

分享到:
评论

相关推荐

    Java 继承和方法重写

    - **方法隐藏**:子类中定义了与父类同名但参数列表不同的方法,不属于重写,只是在子类中隐藏了父类的方法。 **三、继承的应用场景** 1. **代码复用**:通过继承,子类可以共享父类的非私有成员,减少重复代码。...

    方法和变量在继承时的覆盖和隐藏问题

    在Java编程语言中,继承是面向...总结来说,理解Java中方法和变量的覆盖与隐藏规则对于编写正确、高效且可维护的代码至关重要。在编程中应当根据实际需求合理运用继承规则,并注意避免因为覆盖和隐藏带来的潜在问题。

    Java方法的覆盖与隐藏的区别分析

    Java中的方法覆盖(Override)和隐藏(Hiding)是面向对象编程中的两个重要概念,它们涉及到多态性和运行时类型识别(RTTI)。在Java中,这两种情况在处理继承关系时会产生不同的行为。 1. **方法覆盖(Override)*...

    Java中方法的重写与成员变量的隐藏

    "Java中方法的重写与成员变量的隐藏" Java 中方法的重写和成员变量的隐藏是面向对象编程中两个重要的概念。方法的重写是指在子类中重新定义父类中的方法,以便实现多态性,而成员变量的隐藏则是指在子类中定义与...

    方法重写(覆盖)

    在Java中,当子类继承父类时,它可以重写父类中已存在的方法,以实现不同的功能或者优化原有功能。重写允许子类根据自身的需求对父类的行为进行定制。 1. **基本概念**: - 当子类定义了一个与父类中相同名称、...

    java方法的覆盖java方法的覆盖.doc

    同样,静态方法(`static`)也不能被覆盖,而是被隐藏,因为静态方法与类关联,而不是与类的实例关联。 5. **abstract方法**:如果父类方法是抽象的(`abstract`),子类必须覆盖它,除非子类也是抽象的。如果子类不是...

    java中重载、覆盖和隐藏三者的区别分析

    **隐藏与覆盖的区别** 当子类对象被强制转换为父类类型时,对于隐藏的属性,会访问父类中的属性,而对于覆盖的方法,会根据对象的实际类型调用子类的方法,这是由于RTTI的作用。隐藏不受RTTI约束,因此,隐藏是静态...

    重载、重写、重构.md

    #### 重写与覆盖的应用示例: 考虑以下代码片段: ```csharp public class ParentClass { public virtual void VirtualMethod() { Console.WriteLine("ParentClass's VirtualMethod"); } } public class ...

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

    每个类都有自己的构造器,子类可以有与父类同名的构造器,但这不是覆盖,而是隐藏。 4. **静态方法与方法覆盖**: 静态方法也不能被覆盖,因为它们是与类绑定的,而不是与对象绑定。静态方法的调用是基于类的,而...

    两种重写方法的内存机制

    总结起来,`new`关键字主要用于隐藏父类的方法,而不是覆盖。它在子类对象中创建了一个新的同名方法,但不会影响父类引用的行为。而`override`关键字则真正实现了方法的覆盖,不论通过何种引用调用,都会执行子类的...

    区分Java的方法覆盖与变量覆盖

    在Java中,当子类中定义了一个与父类方法完全匹配的方法时,子类的方法就会覆盖父类的方法。例如,在给定的示例中: ```java public class People { public String getName() { return "people"; } } public ...

    《Java语言程序设计(Java7) 入门与提高篇》源代码

    这些章节内容覆盖了Java 7的基础知识,通过实践这些源代码,读者可以更好地理解和掌握Java编程。在学习过程中,不断练习和应用这些知识是至关重要的,因为编程是一项实践性极强的技能。通过解决实际问题,你可以深化...

    Java八股文超精炼面试题资料

    封装是OOP的关键概念,它隐藏了对象的内部实现,只对外提供公共接口,确保外部代码只能通过规定的方式与对象交互。JavaBean就是封装的体现,其属性通常是私有的,通过getter和setter方法访问,确保数据安全。ORM框架...

    论JAVA继承机制中父类与子类的关系

    成员的隐藏与覆盖 - **成员变量的隐藏**:子类中定义的与父类同名的成员变量会隐藏父类中的同名成员变量。这意味着在子类内部,使用变量名时会优先引用子类的成员变量。 - **方法的覆盖**:子类中定义的与父类同名...

    java知识点汇总

    首先,从【标题】:“java知识点汇总” 和【描述】:“内容较杂,有java初中高级知识点,也有Java web架构及原理”来看,涉及的内容包括了Java的序列化与反序列化、IO流的基础知识、多态的概念、泛型的应用、反射...

    Java开发示例代码

    5. **构造方法与覆盖**:构造方法不能被覆盖(override),因为它们没有返回类型,不是常规的方法。 6. **访问权限**:实例方法可以直接调用本类的类方法(静态方法),但不能直接调用超类的实例方法或类方法,也不...

    Java面试题及答案.

    在解答这些问题之前,首先需要了解Java中几个关键的概念,包括继承、方法重写、静态方法与实例方法、抽象类和抽象方法,以及字符串和基本数据类型的连接问题。 1. 继承与方法重写 继承是面向对象编程的一个基本特性...

    java习题集与参考答案

    【Java习题集与参考答案】相关知识点 Java是一门广泛使用的高级编程语言,尤其在企业级应用开发中占据重要地位。习题集是学习Java过程中必不可少的一部分,它可以帮助我们巩固理论知识,提升实践能力。Java习题通常...

    广药java考试题目

    隐藏(Hiding)通常指的是子类中存在与父类相同签名的方法,但是并没有特殊的关键字声明如`@Override`,这并不构成方法重载。 - B. 覆盖(Overriding)发生在继承关系中,子类覆盖父类的方法,需要相同的参数列表和...

    java笔记 java笔记

    - **方法覆盖**:子类重写父类的方法。 - **多态分类**:编译时多态和运行时多态。 - **运行时多态的三原则**:替换原则、保护原则、安全原则。 - **`instanceof`运算符**:判断对象是否属于某个类或接口的实例。 #...

Global site tag (gtag.js) - Google Analytics