Java学习笔记之继承

一、继承的基础

在Java术语中,被继承的类叫超类(superclass),继承超类的类叫子类(subclass).

举例说明:

 1 class Box
 2 {
 3     public double width;
 4     public double height;
 5     public double depth;
 6
 7     //重载构造方法
 8     public Box(Box ob)
 9     {
10         width = ob.width;
11         height = ob.height;
12         depth = ob.depth;
13     }
14
15     public Box(double w, double h, double d)
16     {
17         width = w;
18         height = h;
19         depth = d;
20     }
21
22     public Box()
23     {
24         width = -1;
25         height = -1;
26         depth = -1;
27     }
28
29     public Box(double len)
30     {
31         width = height = depth = len;
32     }
33
34     //计算体积
35     public double volume()
36     {
37         return width * height * depth;
38     }
39 }
40
41 //下面的类继承自类Box
42 class BoxWeight extends Box
43 {
44     double weight;
45
46     //BoxWeight的构造方法
47     BoxWeight (double w, double h, double d, double m)
48     {
49         width = w;
50         height = h;
51         depth = d;
52         weight = m;
53     }
54 }
55
56 public class DemoBoxWeight
57 {
58     public static void main(String args[])
59     {
60         BoxWeight mybox1 = new     BoxWeight(10, 20, 15, 34.3);
61         BoxWeight mybox2 = new     BoxWeight(2, 3, 4, 0.076);
62         double vol;
63
64         vol = mybox1.volume();
65         System.out.println("Volume of mybox1 is " + vol);
66         System.out.println("Weight of mybox1 is " + mybox1.weight);
67         System.out.println();
68         vol = mybox2.volume();
69         System.out.println("Volume of mybox2 is " + vol);
70         System.out.println("Weight of mybox2 is " + mybox2.weight);
71     }
72 }

如42行所示,声明一个继承超类的类,需要用到关键字extends,形式如下:

class subclass-name extends superclass-name {
 // body of class
} 

子类BoxWeight 包括超类Box所有成员,这就是为什么在49-51行中子类可以直接给超类的成员赋值,并且子类对象mybox1可以调用超类方法volume()的原因。而且一个子类可以是另一个类的超类。

但是一个子类只允许有一个超类(这与C++不同,C++中派生类可以继承多个基础类),任何类不能成为自己的超类。

运行结果:

继承的一个主要优势在于一旦你已经创建了一个超类,而该超类定义了适用于一组对象的属性,它可用来创建任何数量的说明更多细节的子类。每一个子类能够正好制作它自己的分类。上面的BoxWeight类继承了Box并增加了一个重量属性。 每一个子类只增添它自己独特的属性。

二、成员的访问权限和继承

尽管子类包括超类的所有成员,但是它不能访问超类中被声明成private的成员,一个被类定义成private的类成员为此类私有,它不能被该类外的所有代码访问。

类成员的访问控制通常有四种public,protected,default,private,下图对各种控制模式的允许访问范围作一个总结:

三、超类变量可以引用子类对象

 1 class Box
 2 {
 3     public double width;
 4     public double height;
 5     public double depth;
 6
 7     //重载构造方法
 8     public Box(Box ob)
 9     {
10         width = ob.width;
11         height = ob.height;
12         depth = ob.depth;
13     }
14
15     public Box(double w, double h, double d)
16     {
17         width = w;
18         height = h;
19         depth = d;
20     }
21
22     public Box()
23     {
24         width = -1;
25         height = -1;
26         depth = -1;
27     }
28
29     public Box(double len)
30     {
31         width = height = depth = len;
32     }
33
34     //计算体积
35     public double volume()
36     {
37         return width * height * depth;
38     }
39 }
40
41 //下面的类继承自类Box
42 class BoxWeight extends Box
43 {
44     double weight;
45
46     //BoxWeight的构造方法
47     BoxWeight (double w, double h, double d, double m)
48     {
49         width = w;
50         height = h;
51         depth = d;
52         weight = m;
53     }
54 }
55 class RefDemo
56 {
57       public static void main(String args[])
58       {
59         BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
60         Box plainbox = new Box();
61         double vol;
62
63         vol = weightbox.volume();
64         System.out.println("Volume of weightbox is " + vol);
65         System.out.println("Weight of weightbox is " +
66                            weightbox.weight);
67         System.out.println();
68         // assign BoxWeight reference to Box reference
69         plainbox = weightbox;
70
71         vol = plainbox.volume(); // OK, volume() defined in Box
72         System.out.println("Volume of plainbox is " + vol);
73
74         /* The following statement is invalid because plainbox
75            does not define a weight member. */
76     //  System.out.println("Weight of plainbox is " + plainbox.weight);
77       }
78     }

weightbox是BoxWeight对象的一个引用,plainbox是Box对象的一个引用(关于JAVA中引用的概念和C++有些不同,可以参考http://blog.sina.com.cn/s/blog_7fb1495b01012sfn.html,写的很详细)。既然 BoxWeight是Box的一个子类,允许用一个weightbox对象的引用给plainbox赋值,但是plainbox是不可以访问weight的,因为超类不知道子类增加的属性weight,所以最后一行被注释掉,Box的引用访问weight域是不可能的,因为它没有定义这个域。

四、关于super

super有两种通用形式。第一种调用超类的构造方法。第二种用来访问被子类的成员隐藏的超类成员。

  • 使用super调用超类构造函数

考虑下面BoxWeight()的改进版本:

class BoxWeight extends Box
{
    double weight;

    //BoxWeight的构造方法
    BoxWeight (double w, double h, double d, double m)
    {
        super(w, h, d);// 调用超类构造方法
        weight = m;
    }
}

这样即使Box完全可以把成员width,height,depth声明为private,以为子类在初始化这些成员时并没有自己动手,而是调用超类的构造方法去初始化这些值(超类自己的构造方法显然可以访问自己private成员),这样有利于超类的封装。而且超类将根据super里面参数的形式决定调用哪一个构造方法,看下面程序:

  1 class Box
  2 {
  3     //成员全部“私有化”
  4     private double width;
  5     private double height;
  6     private double depth;
  7
  8     //重载构造方法
  9     public Box(Box ob)
 10     {
 11         width = ob.width;
 12         height = ob.height;
 13         depth = ob.depth;
 14     }
 15
 16     public Box(double w, double h, double d)
 17     {
 18         width = w;
 19         height = h;
 20         depth = d;
 21     }
 22
 23     public Box()
 24     {
 25         width = -1;
 26         height = -1;
 27         depth = -1;
 28     }
 29
 30     public Box(double len)
 31     {
 32         width = height = depth = len;
 33     }
 34
 35     //计算体积
 36     public double volume()
 37     {
 38         return width * height * depth;
 39     }
 40 }
 41
 42 //下面的类继承自类Box
 43 class BoxWeight extends Box
 44 {
 45     double weight;
 46
 47     //用super调用BoxWeight的构造方法
 48     BoxWeight(BoxWeight ob)
 49     {
 50         super(ob);
 51         weight = ob.weight;
 52     }
 53
 54     BoxWeight (double w, double h, double d, double m)
 55     {
 56         super(w, h, d);
 57         weight = m;
 58     }
 59       // default constructor
 60       BoxWeight() {
 61         super();
 62         weight = -1;
 63       }
 64
 65       BoxWeight(double len, double m) {
 66         super(len);
 67         weight = m;
 68       }
 69 }
 70 public class myJavaTest
 71 {
 72     public static void main(String args[]) {
 73         BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
 74         BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
 75         BoxWeight mybox3 = new BoxWeight(); // default
 76         BoxWeight mycube = new BoxWeight(3, 2);
 77         BoxWeight myclone = new BoxWeight(mybox1);
 78         double vol;
 79
 80         vol = mybox1.volume();
 81         System.out.println("Volume of mybox1 is " + vol);
 82         System.out.println("Weight of mybox1 is " + mybox1.weight);
 83         System.out.println();
 84
 85         vol = mybox2.volume();
 86         System.out.println("Volume of mybox2 is " + vol);
 87         System.out.println("Weight of mybox2 is " + mybox2.weight);
 88         System.out.println();
 89
 90         vol = mybox3.volume();
 91         System.out.println("Volume of mybox3 is " + vol);
 92         System.out.println("Weight of mybox3 is " + mybox3.weight);
 93         System.out.println();
 94
 95         vol = myclone.volume();
 96         System.out.println("Volume of myclone is " + vol);
 97         System.out.println("Weight of myclone is " + myclone.weight);
 98         System.out.println();
 99         vol = mycube.volume();
100         System.out.println("Volume of mycube is " + vol);
101         System.out.println("Weight of mycube is " + mycube.weight);
102         System.out.println();
103       }
104     }

运行结果:

这里特别注意这个构造方法:

    BoxWeight(BoxWeight ob)
    {
        super(ob); //子类对象赋给超类对象
        weight = ob.weight;
    }
    

可以看出一个超类引用了子类对象,但是超类只知道它自己的成员,而weight它是不知道的,需要单独初始化。

特别记住,super()必须是子类构造方法中第一个执行的语句。

  • super的第二种用法

通用形式:super.超类的成员域, 其中“超类的成员域”可以是成员变量和成员方法。多数是用于超类成员名被子类中同样的成员名隐藏的情况,看一个简单的例子:

1 class A
 2 {
 3    int xiaoming;
 4 }
 5
 6 class B extends A {
 7   int xiaoming; // 这子类中的同名变量xiaoming会隐藏超类中的xiaoming
 8
 9   B(int a, int b) {
10     super.xiaoming = a; // xiaoming in A
11     xiaoming = b; // xiaoming in B
12   }
13
14   void show()
15  {
16     System.out.println("xiaomingin superclass: " + super.xiaoming);
17     System.out.println("xiaoming in subclass: " + xiaoming);
18   }
19 }
20
21 class UseSuper
22  {
23     public static void main(String args[])
24       {
25          B subOb = new B(1, 2);
26
27          subOb.show();
28       }
29   }

输出如下:

xiaoming in superclass: 1

xiaoming in subclass: 2

这个例子只是展示了super可以访问被子类隐藏的超类的成员变量,但是不要忘记,super同样可以访问被子类隐藏的超类的成员方法。

Java学习笔记之继承,布布扣,bubuko.com

时间: 2024-08-02 02:49:50

Java学习笔记之继承的相关文章

Java学习笔记-4.继承与多态

一.继承机制 1.继承:允许一个类作为另一个类的扩充版本 2.单继承:一个类只继承了一个父类    多继承:一个类继承了多个父类 Java只支持单继承,C++支持多继承 二.类的继承 1.形式: class SubClass extends BaseClass { //子类类体,定义子类的新成员 } Java中所有的类都直接或间接地继承类 java.lang.Object 2.构造方法 (1)显式构造方法    形式:super(参数表); 系统执行到这条语句时,会根据参数表判断调用父类中哪个构

黑马程序员——JAVA学习笔记四(继承、接口、内部类)

1,    通过extends关键字让类与类之间产生继承关系.多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需定义这些属性和行为,只要继承那个类即可,已存在的类叫做超类,基类,或父类.新类称为子类,派生类,孩子类. 子类可以直接访问父类中的非私有的属性和行为.子类无法继承父类中私有的内容.JAVA不支持多继承,只支持单继承,多实现. 继承提高了代码复用性,让类与类之间产生了关系.为多态提供了前提. 2,    super关键字代表父类中成员变量内存空间的标示.两个作用

java学习笔记(六)继承

继承是面向对象编程中最重要的特征之一,它允许通过继承一个已经存在的类,来编写一个新类.已有的类称为父类,也可以称为基类,超类,新类称为子类也称为派生类. 继承使用关键字extends,用在类名之后,例:public void class salary extends Employee(){ } 子类salary 继承父类Employee java中的类只能继承一个类. 子类能继承父类中用public protected 修饰的成员. 继承的单根性(单继承):一个java类只能有一个父类. 继承的

Java学习笔记3——继承

继承 继承的好处:子类拥有父类的所有属性和方法,peivate修饰的无效:实现代码复用 class 子类 extends 父类 例如: class Dog extends Animal{              ...... } 父类: package com.imooc; public class Animal {  public int age;  public String name;  public void eat(){   System.out.println("动物具有吃东西&q

java学习笔记10--泛型总结

java学习笔记系列: java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3--类与对象的基础 java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址:http://www.cnblogs.com/archimedes/p/java-study-note10.html,转载

Java学习笔记心得——初识Java

初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开始走进Java的世界.  Java产生的历史 Java来自于Sun公司的一个叫Green Project中撰写的程序语言,全球信息网(World Wide Web)兴起,Java Applet成为网页互动技术的代表,特别适合于Internet应用程序开发. Java语言的特点 1.面向对象 这是Java最重要

java学习笔记8--接口总结

接着前面的学习: java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3--类与对象的基础 java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址:http://www.cnblogs.com/archimedes/p/java-study-note8.html,转载请注明源地址. 生活中的接口: 什么是接口? 一个Java接口是一些方法特

java学习笔记3——java关键字

java学习笔记3——java关键字 虽然老师说不用刻意的去记忆,但是我还是在网上找到了非常详细的注解,再次收藏 关键字的类型表: 各个关键字的详细注解和实例,按首字母排序: 1.abstract abstract 关键字可以修改类或方法. abstract 类可以扩展(增加子类),但不能直接实例化. abstract 方法不在声明它的类中实现,但必须在某个子类中重写. -示例- public abstract class MyClass{ } public abstract String my

java学习笔记(三)java中的修饰符abstract、static与final

一.四种访问级别的访问范围 访问级别 访问修饰符 同类 同包 子类 不同的包 公开 public 受保护 protected 默认 没有访问修饰符 私有的 private 二.使用abstract修饰符需要遵守的语法规则 1.抽象类中可以没有抽象方法,但是包含抽象方法的类必须定义为抽象类,即用abstract修饰: 2.抽象类跟抽象方法不能被final修饰符修饰: 3.抽象类中可以有非抽象方法,因为继承抽象类的子类必须重写父类中所有的抽象方法,因此抽象类中不能有抽象构造方法和抽象静态方法: 4.