Java学习笔记之继承
一、继承的基础
在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.8(java学习笔记)继承与方法的重写
继承 在java中可以通过继承提高代码的复用率. 例如A继承了B,就可以是 例如,首先有一个类似Person,这个类中有有一些属性和方法,我们再新建一个Student类,其中有一部分属性和方法与Per ...
- Java 学习笔记(6)——继承
之前说过了Java中面向对象的第一个特征--封装,这篇来讲它的第二个特征--继承.一般在程序设计中,继承是为了减少重复代码. 继承的基本介绍 public class Child extends Pa ...
- Java学习笔记之——继承
父类(基类):动物 子类:猫.狗.狼.老虎 如果子类继承于父类,则会自动拥有父类的所有非私有属性和方法,不会继承构造方法 父类和子类要满足一种关系:子类是父类的一种 Java中只支持单继承:一个子类只 ...
- java学习笔记1——继承
通过在类的声明中加入extends子句创建一个子类并继承父类的成员变量和方法.如: class SubClass extends SuperClass{ ... } 若SuperClass是另一个类的 ...
- 0022 Java学习笔记-面向对象-继承、多态、组合
继承的特点 单继承:每个子类最多只有一个直接父类,注意是直接父类,间接父类个数不限 注意父类的概念:A-->B-->C-->D,在这里,ABC都是D的父类,C是D的直接父类,AB是D ...
- java学习笔记之基础篇
java选择语句之switch //switch可以用于等值判断 switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字 ...
- java学习笔记6--类的继承、Object类
接着前面的学习: java学习笔记5--类的方法 java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记 ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
- 0032 Java学习笔记-类加载机制-初步
JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...
随机推荐
- nginx修改内核参数
1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件 数量的限制(这是因为系统为 ...
- 【LeetCode】232 & 225 - Implement Queue using Stacks & Implement Stack using Queues
232 - Implement Queue using Stacks Implement the following operations of a queue using stacks. push( ...
- 转-sketch技巧
10个帮你UI设计提速的Sketch使用技巧 2015-4-11 09:59| 发布者: yuanxingbbs| 查看: 1129| 评论: 0 选择使用Sketch的理由很多,因为好奇跟风安装 ...
- javascript中=、==、===区别详解
javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...
- 免费CDN
什么是CDN? CDN (Content Delivery Network) ,CDN 是包含可分享代码库的服务器网络. CDN公共库是指将常用的JS库存放在CDN节点,以方便广大开发者直接调用.与将 ...
- wifi reaver
PIN码的格式很简单, 八位十进制数,最后一位(第8位)为校验位(可根据前7位算出),验证时先检测前4位,如果一致则反馈一个信息,所以只需1万次就可完全扫描一遍前4位,前4位确定下来的话,只需再试10 ...
- mysql-python模块编译问题解决
解决方法:yum -y install mysql-devel libxml2 libxml2-dev libxslt* zlib gcc openssl [root@localhost MySQL- ...
- python 加密解密(base64, AES)
1. 使用base64 s1 = base64.encodestring('hello world') s2 = base64.decodestring(s1) print s1, s2 结果 1 2 ...
- UVa11997K Smallest Sums(优先队列)
K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pick exactly ...
- Base64把图片、文件转码成字符串(互转)
文件Base64以后会翻倍的涨,例如一张52kb的图片 base64以后string文件大小为185kb,在通过string转回图片为135kb 图片转文字: UIImage *_originIm ...