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

继承中的构造方法及覆盖与隐藏

 
阅读更多
继承中的构造方法
一、无参构造函数(默认构造函数)与有参构造函数
子类的所有构造方法都必须调用父类的一个构造方法,如果不显示指定调用父类的哪个构造方法,就默认调用父类的无参构造方法.
class A
{
   //A() { System.out.println("A()");}
   A(int i) { System.out.println("A(i)");}
}
class B extends A
{
    B()  { }
    public  static void  main(String []a)
   {  B b=new B(); }
}
编译时显示:
B.java:8: 找不到符号
符号: 构造函数 A()
位置: 类 A
    B(  )  { }
           ^
1 错误
即:创建一个子类的对象实例的时候,必先调用父类的无参数的构造函数(默认构造函数),
假如父类有带参数的构造函数,那么系统将不会给它创建无参数的构造函数,这时,子类在实例化的时候,
因为找不到父类的默认构造函数,编译器将会报错,但如果在子类的构造函数中指定用父类的带参数的构造函数的时候,或者在父类中加一个无参数的构造函数,就不会报错。我们假设A是B的父类,B是A的子类。
1、如果程序员没有给类A没有提供构造函数,则编译器会自动提供一个默认的无参数的构造函数,如果用户提供了自己的构造函数,则编译器就不再提供默认的无参数构造函数。
2、子类B实例化时会自动调用父类A的默认构造函数,所以如果A的默认的无参数的构造函数为private,则编译器会报错,而如果A没有提供默认的无参数的构造函数,而提供了其他类型的构造函数,编译器同样会报错,因为B找不到A的默认无参数构造函数。所以,我们最好给父类A提供一个无参数的构造函数。
3、或者在B的构造函数中显示的调用父类A的有参构造函数。super(parameter)
二、成员继承中的隐藏和覆盖
首先看一下JAVA中方法和变量在继承时的覆盖和隐藏规则
1.父类的实例变量和静态变量能被子类的同名变量隐藏
2.父类的静态方法被子类的同名静态方法隐藏
3.父类的实例方法被子类的同名实例方法覆盖

还有几点需要注意的是
1.不能用子类的静态方法隐藏 父类中同样标识(也就是返回值 名字 参数都一样)的实例方法
2.不能用子类的实例方法覆盖 父类中同样标识的静态方法
3.这点儿请注意,就是变量只会被隐藏不会被覆盖,无论他是实例变量还是静态变量,而且,子类的静态变量可以隐藏父类的实例变量,子类的实例变量可以隐藏 父类的静态变量
总结:
1.同名的实例方法被覆盖 ,同名的静态方法被隐藏,
2.隐藏 和覆盖 的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏 的变量和方法,而不能访问父类被覆盖 的方法。(类的多态性)
3.如果需要访问父类被隐藏 的实例变量,加上super就好了。
4.如果需要访问父类被覆盖的方法,加上super就好了。
例1:变量隐藏:子类拥有了两个相同名字的变量,一个来自父类,一个是自己定义;当子类执行继承自父类的操作时,处理的是继承自父类的变量,而当子类执行它自己定义的方法时,所操作的就是它自己的变量,而把继承自父类的变量“隐藏”起来了。
class A
{
  protected int  a;
  A(int a) {setA(a+10);}
  public void setA(int x)   {  a=x;  }
  public void showA() {System.out.println("A:showA(): a="+a);}
  public void show() {System.out.println("A:show() :a="+a);}
}
class B2 extends A
{
   protected int a,b;
   B2(int x1, int y1)   { super(x1);   setB(x1+100, y1+100);   }
   public void setB(int x1, int y1)  {    a=x1;    b=y1;  }
   public void show()
   {
       //super.show();
    System.out.println("B:show():a="+a+" B:b="+b);
}
    public  static void  main(String []a)
{
    B2 b1;
    b1=new B2(1,2);
    b1.show();
    b1.showA();
}
}
----------运行 ----------
B:show():a=101 B:b=102
A:showA(): a=11

例2:部分覆盖:super.原父类方法名+其它语句

class A
{
  protected int  a;
  A(int a) {setA(a+10);}
  public void setA(int x)   {  a=x;  }
  public void showA() {System.out.println("A:showA(): a="+a);}
  public void show() {System.out.println("A:show() :a="+a);}
}
class B2 extends A
{
   protected int a,b;
   B2(int x1, int y1)   { super(x1);   setB(x1+100, y1+100);   }
   public void setB(int x1, int y1)  {    a=x1;    b=y1;  }
   public void show()
   {
          super.show();
    System.out.println("B:show():a="+a+" B:b="+b);
}
    public  static void  main(String []a)
{
    B2 b1;
    b1=new B2(1,2);
    b1.show();
    //b1.showA();
}
}
----------运行 ----------
A:show() :a=11
B:show():a=101 B:b=102

例3:show是实例方法被覆盖,转化为父类对象时,由于是子类对象所以调用本身类的方法,如果是父类对象,则调用父类的方法。showA是父类的方法而子类中无该方法,所以调用父类的方法,访问父类的成员。
class A
{
   protected  static int  a;
  A(int a) {setA(a+10);}
  public  static void setA(int x)   {  a=x;  }
  public static void showA() {System.out.println("A:showA(): a="+a);}
  public   void show() {System.out.println("A:show() :a="+a);}
}
class B2 extends A
{
   protected static int a,b;
   B2(int x1, int y1)   { super(x1);   setB(x1+100, y1+100);   }
   public static void setB(int x1, int y1)  {    a=x1;    b=y1;  }
   public    void show()
   {
      //super.show();
    System.out.println("B:show():a="+a+" B:b="+b);
}
    public  static void  main(String []a)
{
    A a1=new A(1);
    B2 b1;
    a1.show();
    b1=new B2(1,2);
    a1=b1;
    a1.show(); 
    a1.showA();
}
}
----------运行 ----------
A:show() :a=11
B:show():a=101 B:b=102
A:showA(): a=11

例4:a是静态变量,在子类用有同名变量,所以在子类中a被隐藏。在子类中如果要访问来自父类的a成员需要使用super。
class A
{
   protected  static int  a;
  A(int a) {setA(a+10);}
  public  static void setA(int x)   {  a=x;  }
  public static void showA() {System.out.println("A:showA(): a="+a);}
  public   void show() {System.out.println("A:show() :a="+a);}
}
class B3 extends A
{
   protected static int a,b;
   B3(int x1, int y1)   { super(x1);   setB(x1+100, y1+100);   }
   public static void setB(int x1, int y1)  {    a=x1;    b=y1;  }
   public  void show()
   {
          System.out.println("B:show():a="+a+" B:b="+b+" B:super.a="+super.a);
}
    public  static void  main(String []a)
{
  B3 b1;
    b1=new B3(1,2);
    b1.show();
}
}
结果:
B:show():a=101 B:b=102 B:super.a=11

例5:show是静态方法,属于类的,而不属于某一个对象,所以用a1对象调用show()方法相当于A.show()调用,跟a是那一个父类对象,或者跟子类对象没有任何的关系。
class A
{
   protected  static int  a;
  A(int a) {setA(a+10);}
  public  static void setA(int x)   {  a=x;  }
  public static void showA() {System.out.println("A:showA(): a="+a);}
  public  static void show() {System.out.println("A:show() :a="+a);}
}
class B2 extends A
{
   protected static int a,b;
   B2(int x1, int y1)   { super(x1);   setB(x1+100, y1+100);   }
   public static void setB(int x1, int y1)  {    a=x1;    b=y1;  }
   public   static void show()
   {
      //super.show();
    System.out.println("B:show():a="+a+" B:b="+b);
}
    public  static void  main(String []a)
{
    A a1=new A(1);
    B2 b1;
    a1.show();
    b1=new B2(1,2);
    a1=b1;
    b1.show();
    a1.show(); 
    a1.showA();
}
} ----------运行 ----------
A:show() :a=11
A:show() :a=11
A:showA(): a=11
分享到:
评论

相关推荐

    Java方法继承、方法重载、方法覆盖总结

    在Java编程语言中,方法继承、方法重载、方法覆盖是三个非常重要的概念。它们之间既有关联又有区别,掌握这些概念对于深入理解面向对象编程有着至关重要的作用。 #### 一、Java方法继承 **方法继承**是指在一个类...

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

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

    Java 接口与继承

    `this`和`super`常常用于解决成员变量的隐藏和方法的覆盖问题,尤其是在构造方法中调用其他构造方法或父类的构造方法时。 总的来说,继承和接口是Java中实现代码复用、模块化和扩展性的核心工具。通过合理利用这些...

    Java 继承和方法重写

    4. **方法覆盖与方法隐藏**: - **方法覆盖**:子类中定义了与父类同名、同参数列表的方法,属于重写。 - **方法隐藏**:子类中定义了与父类同名但参数列表不同的方法,不属于重写,只是在子类中隐藏了父类的方法...

    c#中类的继承

    - 在这个例子中,即使 `B` 类中的 `Fun()` 方法与 `A` 类中的 `Fun()` 方法具有相同的签名,但由于使用了 `new` 关键字,子类 `B` 的方法并没有覆盖父类 `A` 的方法。 #### 五、总结 通过上述介绍,我们可以了解...

    java继承与多态教学及练习

    1继承的概念 2继承的实现 3变量隐藏与方法覆盖 4super关键字 5 子类的构造顺序 6Object类 7 final关键字

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

    文章围绕子类继承父类成员的过程、成员变量及方法的赋值、重写、覆盖等问题展开讨论,旨在帮助读者更好地理解Java继承中的重点与难点。 #### 关键词 - 继承机制 - 父类 - 子类 #### 一、超类的属性或方法在继承...

    Java的继承机制详解

    3. 构造方法:子类无法直接继承父类的构造方法,但可以通过`super`关键字在子类构造函数中调用父类的构造方法。子类可以有自定义构造方法,或者使用JVM提供的默认构造方法。 4. 访问修饰符:Java提供了四种访问级别...

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

    在Java中,当子类继承父类,并且子类定义了一个与父类同名、同参数列表的方法时,就发生了方法覆盖。这使得子类对象在调用这个方法时,会执行子类自定义的行为,而不是父类的方法。 方法覆盖的规则和注意事项如下:...

    理学继承接口与泛型PPT课件.pptx

    【理学继承接口与泛型】是编程领域中关于面向对象设计的重要概念,主要涉及到类的继承、接口的使用以及泛型的应用。以下是对这些知识点的详细解释: 1. **类继承**: - 类继承是面向对象编程的一个关键特性,允许...

    java类的继承实例

    当子类有一个与父类同名但参数列表不同的方法时,这种情况称为方法隐藏,而不是覆盖。 **super 关键字** 1. 在子类中,`super` 关键字用来引用父类的对象,可以访问父类的成员。 2. `super` 也可以用于在子类构造器...

    java---- 封装,接口,继承,覆盖,构造过程,多态,static、this、super、final用法

    在Java中,多态可以通过继承和方法覆盖来实现。 **特点:** - **方法覆盖实现多态:** 子类可以覆盖父类的方法,根据运行时的对象类型动态决定调用哪个方法。 - **接口实现多态:** 实现接口的多个类可以拥有相同的...

    4类的继承与派生继承与派生

    - **私有继承(private)**:基类的公共成员和保护成员在派生类中变为私有成员,这通常用于隐藏实现细节。 - **保护继承(protected)**:基类的公共成员变为保护成员,而保护成员保持不变,这适用于需要在子类中使用但...

    JAVA面向对象编程继承性和多态性PPT教案学习.pptx

    在子类的构造方法中,`super(参数)`用于调用父类的构造方法,这是必要的,尤其是在需要初始化父类状态时。 方法覆盖是继承的一个关键特性,子类可以重新定义父类的方法,只要保持方法名、参数列表和返回类型一致。...

    C#中的继承C#中的继承C#中的继承

    3. **成员的隐藏与重写** - 如果子类中定义了与基类同名的方法或属性,那么基类的成员会被隐藏。使用 `new` 关键字表明这是一种有意的隐藏。 ```csharp public class BaseClass { public void Method() { ... }...

    C#子类对基类方法的继承、重写与隐藏详解

    C#子类对基类方法的继承、重写与隐藏是OOP编程中的一些重要概念,掌握这些概念对于学习C#和使用C#编程语言非常重要。下面,我们将通过示例代码详细介绍C#子类对基类方法的继承、重写与隐藏。 一、子类继承基类非...

    实验三Java类的继承与派生

    构造方法不会被继承,但是子类可以通过调用父类的构造方法来初始化父类中的成员变量。通常情况下,子类的构造方法会首先调用父类的构造方法(使用`super`关键字),以便完成父类属性的初始化。 ##### 示例代码 ```...

    Unity基础 C# 第六章 继承与多态.pptx

    当子类需要初始化父类中的某些属性时,可以调用父类的构造方法。默认情况下,子类构造器会调用父类无参的构造器。如果需要调用有参的构造器,则需要使用 `base` 关键字显式指定: ```csharp class Car { public ...

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

    3. **构造器与方法覆盖**: 构造器不能被覆盖,因为它们不遵循方法覆盖的规则。每个类都有自己的构造器,子类可以有与父类同名的构造器,但这不是覆盖,而是隐藏。 4. **静态方法与方法覆盖**: 静态方法也不能被...

Global site tag (gtag.js) - Google Analytics