JAVA-入门 继承(自学笔记)(郝斌)

继承

继承的原则

  • 一个很好的经验:“类B是类A的一个特殊化吗?”
  • 如果是则让类B做类A的子类
class Human
{
    public String name = "彭晨";
    public int age = 22;


}
class Student extends Human
{
    public double score = 99;

}
class Postgraduate extends Student
{

    public String daoshi = "郝斌";

}
class M
{
    public static void main(String[] args)
    {
        Postgraduate  gd = new Postgraduate();
        System.out.printf("%s %d %f %s\n",gd.name,gd.age,gd.score,gd.daoshi);
    }
}

程序运行示例:
————————————————————————————————————————
彭晨 22 99.000000 郝斌
————————————————————————————————————————
  • 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫做类的继承

  • 这个新类被称为子类或者派生类,已有的那个类叫做父类或者叫做基类

  • 继承的好处

    • 代码得到极大的重用
    • 形成一种类的层次体系结构
    • 为多态创造条件(OOP第三个特点)
  • 继承的实现方式

    • class SubClass extends SuperClass

    • {

    • }

同包继承权限问题(重点)

  • 子类的所有方法内部都可以访问父类除私有成员以外的所有成员,所谓子类的所有方法也包括子类的私有方法
  • 通过子类对象名可以访问
    • 父类除私有成员外的所有成员
    • 子类本身的除私有成员外的所有成员
    • 附注,私有成员包括私有属性和私有方法
  • 子类可以继承父类除私有属性和私有方法以外的所有成员
  • 父类的私有成员不可以被子类继承,其他的成员都可以被子类继承
  • 不同包继承问题等讲到包再说!!
class A
{
    public int i;
    protected int j;
    private int k;
    
    public void g()
    {

    }
    protected void f()
    {

    }
    private void b()
    {

    }
}
class B extends A
{
    private void m()
    {
        i = 20;
        j = 30;
        // k =40;  //error k 在 A 中是 private 访问控制
        g();
        f();
    }

}

class M
{
    public static void main(String[] args)
    {
        B bb = new B();
        bb.i = 10;
        bb.j = 40;
        bb.b();
        bb.m();
        bb.k = 3;

    }
}

程序运行示例:
————————————————————————————————————————
M.java:39: 错误: 找不到符号
        bb.b();
          ^
  符号:   方法 b()
  位置: 类型为B的变量 bb
M.java:40: 错误: m() 在 B 中是 private 访问控制
        bb.m();
          ^
M.java:41: 错误: k 在 A 中是 private 访问控制
        bb.k = 3;
          ^
3 个错误
————————————————————————————————————————

子类访问父类成员的三种方式

  • 在子类内部访问父类成员
  • 通过子类对象名访问父类成员
  • 通过子类的类名访问父类成员

经验证,子类通过上述三种方式的任何一种都无法访问父类私有成员,因此我们可以得出结果:

私有成员无法被子类继承

class A
{
    public static int i;
    protected int j;
    private static int k;
}

class B extends A
{
    public static void g()
    {
        i = 20;
        // k = 20;
    }

}
class M
{
    public static void main(String[] args)
    {
        //B bb = new B();
        //bb.i = 99;//OK
        
    B.g();
    System.out.printf("%d\n",B.k);
    /**
    程序运行示例:
    ———————————————————————————
    k 在 A 中是 private 访问控制
    System.out.printf("%d\n",B.k);
                              ^
    1 个错误 
    ————————————————————————————
    */


    System.out.printf("%d\n",B.i);
    /**
    程序运行示例:
    ———————————————————————————
    20
    ————————————————————————————
    */



    }
}

super()相关

class A
{
    public int i;
    public int j;
    public A()
    {

    }
    public A(int i,int j)
    {
        this.i = i;
        this.j = j;
    }

}

class B extends A
{
    public int k;
    public void f(int i)
    {
        // super(i);
                /**
        程序运行示例:
———————————————————————————————————————
M.java:22: 错误: 对super的调用必须是构造器中的第一个语句
        super(i);
             ^
1 个错误
————————————————————————————————————————
         */
    }
    public B(int i,int j,int k)
    {

        // this.i = i; //一定要明白为什么i前面可以加this
        // this.j = j;



        // A(i,j);
        /**
        程序运行示例:
———————————————————————————————————————
        M.java:24: 错误: 找不到符号
        A(i,j);
        ^
  符号:   方法 A(int,int)
  位置: 类 B
1 个错误
————————————————————————————————————————
         */


        // super(i,j);//OK
                /**
        程序运行示例:
———————————————————————————————————————
10 39 22
————————————————————————————————————————
         */

        this.k = k;
    }



}
class M
{
    public static void main(String[] args)
    {
        B bb = new B(10,39,22);
        System.out.printf("%d %d %d\n",bb.i,bb.j,bb.k);
  
    }
}

上述代码总结:

1、 每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候 就会报错。

2、如果显示的写出super()语句,则必须保证该语句是第一条语句,否则会出错

3、super();如果不写,则编译器会自动添加,所以此时如果父类没有无参的构造函数就会出错。

4、既可以显示写super();前提是父类必须有无参的构造函数

5、调用父类的构造函数的语句必须借助于super(),不能直接写父类的的类名,该与C++不同

6、一个构造函数中不能写多个super(参数列表)语句;

总结

  • 私有不能被继承
  • 私有物理上已经被继承过来,只不过逻辑上程序员不能去访问它
  • 因此继承必须慎重,否则会浪费内存
  • Java只支持单继承,不允许多重继承(这一缺陷通过接口来稍稍弥补了一下)
  • 单继承就是一个类只能有一个父类
  • 多继承就是一个类可以多个父类
  • 可以有多层继承,即一个类可以继承某一个类的子类,如类B继承了类A,类C又可以继承类B,那么类C也间接继承了类A
  • 子类可以继承父类所有的成员变量和成员方法,但子类永远无法继承父亲的构造方法,在子类的构造方法中可使用语句super(参数列表)调用父类的构造方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章