一、继承的基础

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

举例说明:

 class Box
{
public double width;
public double height;
public double depth; //重载构造方法
public Box(Box ob)
{
width = ob.width;
height = ob.height;
depth = ob.depth;
} public Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
} public Box()
{
width = -1;
height = -1;
depth = -1;
} public Box(double len)
{
width = height = depth = len;
} //计算体积
public double volume()
{
return width * height * depth;
}
} //下面的类继承自类Box
class BoxWeight extends Box
{
double weight; //BoxWeight的构造方法
BoxWeight (double w, double h, double d, double m)
{
width = w;
height = h;
depth = d;
weight = m;
}
} public class DemoBoxWeight
{
public static void main(String args[])
{
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
double vol; vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.println("Weight of mybox1 is " + mybox1.weight);
System.out.println();
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.println("Weight of mybox2 is " + mybox2.weight);
}
}

如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,下图对各种控制模式的允许访问范围作一个总结:

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

 class Box
{
public double width;
public double height;
public double depth; //重载构造方法
public Box(Box ob)
{
width = ob.width;
height = ob.height;
depth = ob.depth;
} public Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
} public Box()
{
width = -1;
height = -1;
depth = -1;
} public Box(double len)
{
width = height = depth = len;
} //计算体积
public double volume()
{
return width * height * depth;
}
} //下面的类继承自类Box
class BoxWeight extends Box
{
double weight; //BoxWeight的构造方法
BoxWeight (double w, double h, double d, double m)
{
width = w;
height = h;
depth = d;
weight = m;
}
}
class RefDemo
{
public static void main(String args[])
{
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box();
double vol; vol = weightbox.volume();
System.out.println("Volume of weightbox is " + vol);
System.out.println("Weight of weightbox is " +
weightbox.weight);
System.out.println();
// assign BoxWeight reference to Box reference
plainbox = weightbox; vol = plainbox.volume(); // OK, volume() defined in Box
System.out.println("Volume of plainbox is " + vol); /* The following statement is invalid because plainbox
does not define a weight member. */
// System.out.println("Weight of plainbox is " + plainbox.weight);
}
}

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里面参数的形式决定调用哪一个构造方法,看下面程序:

 class Box
{
//成员全部“私有化”
private double width;
private double height;
private double depth; //重载构造方法
public Box(Box ob)
{
width = ob.width;
height = ob.height;
depth = ob.depth;
} public Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
} public Box()
{
width = -1;
height = -1;
depth = -1;
} public Box(double len)
{
width = height = depth = len;
} //计算体积
public double volume()
{
return width * height * depth;
}
} //下面的类继承自类Box
class BoxWeight extends Box
{
double weight; //用super调用BoxWeight的构造方法
BoxWeight(BoxWeight ob)
{
super(ob);
weight = ob.weight;
} BoxWeight (double w, double h, double d, double m)
{
super(w, h, d);
weight = m;
}
// default constructor
BoxWeight() {
super();
weight = -1;
} BoxWeight(double len, double m) {
super(len);
weight = m;
}
}
public class myJavaTest
{
public static void main(String args[]) {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
BoxWeight mybox3 = new BoxWeight(); // default
BoxWeight mycube = new BoxWeight(3, 2);
BoxWeight myclone = new BoxWeight(mybox1);
double vol; vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.println("Weight of mybox1 is " + mybox1.weight);
System.out.println(); vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.println("Weight of mybox2 is " + mybox2.weight);
System.out.println(); vol = mybox3.volume();
System.out.println("Volume of mybox3 is " + vol);
System.out.println("Weight of mybox3 is " + mybox3.weight);
System.out.println(); vol = myclone.volume();
System.out.println("Volume of myclone is " + vol);
System.out.println("Weight of myclone is " + myclone.weight);
System.out.println();
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
System.out.println("Weight of mycube is " + mycube.weight);
System.out.println();
}
}

运行结果:

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

    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学习笔记之继承的更多相关文章

  1. 1.8(java学习笔记)继承与方法的重写

    继承 在java中可以通过继承提高代码的复用率. 例如A继承了B,就可以是 例如,首先有一个类似Person,这个类中有有一些属性和方法,我们再新建一个Student类,其中有一部分属性和方法与Per ...

  2. Java 学习笔记(6)——继承

    之前说过了Java中面向对象的第一个特征--封装,这篇来讲它的第二个特征--继承.一般在程序设计中,继承是为了减少重复代码. 继承的基本介绍 public class Child extends Pa ...

  3. Java学习笔记之——继承

    父类(基类):动物 子类:猫.狗.狼.老虎 如果子类继承于父类,则会自动拥有父类的所有非私有属性和方法,不会继承构造方法 父类和子类要满足一种关系:子类是父类的一种 Java中只支持单继承:一个子类只 ...

  4. java学习笔记1——继承

    通过在类的声明中加入extends子句创建一个子类并继承父类的成员变量和方法.如: class SubClass extends SuperClass{ ... } 若SuperClass是另一个类的 ...

  5. 0022 Java学习笔记-面向对象-继承、多态、组合

    继承的特点 单继承:每个子类最多只有一个直接父类,注意是直接父类,间接父类个数不限 注意父类的概念:A-->B-->C-->D,在这里,ABC都是D的父类,C是D的直接父类,AB是D ...

  6. java学习笔记之基础篇

    java选择语句之switch   //switch可以用于等值判断 switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字 ...

  7. java学习笔记6--类的继承、Object类

    接着前面的学习: java学习笔记5--类的方法 java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记 ...

  8. 0035 Java学习笔记-注解

    什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...

  9. 0032 Java学习笔记-类加载机制-初步

    JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...

随机推荐

  1. Linux共享内存(一)

    inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...

  2. IOS AutoLayout 遍历修改约束

    self.cvv2View.hidden = YES; self.periodView.hidden = YES; [self.contentView.constraints enumerateObj ...

  3. 解决Asp.net Mvc返回JsonResult中DateTime类型数据格式的问题

    问题背景: 在使用asp.net mvc 结合jquery esayui做一个系统,但是在使用使用this.json方法直接返回一个json对象,在列表中显示时发现datetime类型的数据在转为字符 ...

  4. [转]inux之touch命令

    转自:http://www.2cto.com/os/201309/242518.html Linux学习之touch命令   Linux的touch命令一般用来更改文档或目录的日期时间,包括存取时间和 ...

  5. linux下磁盘的挂载与卸载

    Linux下每个文件系统都有独立的inode,block,super block等信息,这个文件系统要挂载到目录树才可以使用,将文件系统与目录树结合的操作称为挂载,反之则为卸载. 也就是说,挂载点一定 ...

  6. Zabbix监控Linux磁盘I/O

    东西都上传到这里了: https://github.com/RexKang/Zabbix/tree/master/OS/Linux-disk-discovery   需要用到的东西: Zabbix的L ...

  7. D.xml

    pre{ line-height:1; color:#1e1e1e; background-color:#f0f0f0; font-size:16px;}.sysFunc{color:#627cf6; ...

  8. WebApi参数传递

    c# webapi的参数传递方式:1.查询字符串(query string):2.内容主体(content body) 当然也有cookie或url部分或头部信息(header)等其它传方式,这里仅讨 ...

  9. PV3D学习笔记-导入DAE模型

      网上关于PV3D导入DAE模型的例子都非常多,可惜我研究了半天,一个都没成功,或者是破面问题,或者是贴图不显示,再或者贴图乱掉了.今天晚上终于搞定,心得发上来. 制作模型的软件是SketchUp ...

  10. KMP算法——Javascript实现

    腾讯和阿里的笔试刚过去了,里面有很多题都很值得玩味的.之前Blog积累的很多东西,还要平时看的书,都有很大的帮助.这个深有体会啊! 例如,腾讯有一道算法题是吃香蕉(好邪恶的赶脚..),一次吃一根或者两 ...