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

继承中的构造方法
一、无参构造函数(默认构造函数)与有参构造函数
子类的所有构造方法都必须调用父类的一个构造方法,如果不显示指定调用父类的哪个构造方法,就默认调用父类的无参构造方法.
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值