复用类有两种实现方式。

  • 在新的类中产生现有类的对象,由于新的类是由现有类的对象所组成,所以这种方法称之为组合。
  • 采用继承实现。

一  组合语法

下面创建两个类WaterSource和SprinklerSystem。其中SprinklerSystem中包含WaterSource的对象引用。

class WaterSource {
//如果定义时没有初始化,则基本类型会被自动初始化为0,对象引用初始化为Null
private String s;
WaterSource(){
System.out.println("WaterSource()");
s = "Constructed";
}
} public class SprinklerSystem {
private String value1,value2,value3,value4;
//定义时初始化
private WaterSource source = new WaterSource();
private int i;
private float f;
public String toString() {
return
"value1 = " + value1 + " " +
"value2 = " + value2 + " " +
"value3 = " + value3 + " " +
"value4 = " + value4 + "\n" +
"i = " + i + " " + "f = " + f + " " +
"source = " + source;
} public static void main(String[] args) {
SprinklerSystem sprinklers = new SprinklerSystem();
System.out.println(sprinklers);
}
}

运行结果如下:

WaterSource()
value1 = null value2 = null value3 = null value4 = null
i = 0 f = 0.0 source = WaterSource@15db9742

注意:如果把一个对象以String类型输出,则默认调用的是该对象的toString()方法。

类中成员变量如果是基本基本类型则默认被初始化为零,如果是对象引用则会被初始化为null。

我们也可以自己去初始化他们:

  • 在定义成员变量的时候初始化,比如private String s1 = "happy";这意味着他们能够在构造函数被调用之前初始化。
  • 在类的构造函数中初始化;
  • 在使用这些成员变量之前初始化,这种方式称之为惰性初始化;
  • 使用实例初始化{s1 = "happy";}。

二 继承语法

Java创建一个类时,默认都是继承于Object,除非自己指定从哪个类继承。

class Cleanser{
private String s = "Cleanser";
public void append(String a) { s += a; }
public void dilute(){append(" dilute()");}
public void apply() {append(" apply()");}
public void scrub() {append(" scrub()");}
public String toString() {return s;} public static void main(String[] args) {
Cleanser x = new Cleanser();
x.dilute();
x.apply();
x.scrub(); System.out.println(x);
} } public class Detergent extends Cleanser {
public void scrub() {
append(" Detergent.scrub()");
super.scrub();
} public void foam() {append(" foam()");} public static void main(String[] args) {
Detergent x = new Detergent();
x.dilute();
x.apply();
x.scrub();
x.foam();
System.out.println(x);
System.out.println("Testing base class:"); Cleanser.main(args);
} }

运行结果如下:

Cleanser  dilute()  apply() Detergent.scrub()  scrub() foam()
Testing base class:
Cleanser dilute() apply() scrub()

看以看到继承使用的是关键字extends,如果在子类中想调用父类方法,可以使用super.*。

1、初始化父类

在创建一个子类对象时,父类构造器总会在子类构造器之前被调用。

class Art{
Art(){
System.out.println("Art constructor");
}
} class Drawing extends Art{
Drawing(){
System.out.println("Drawing constructor");
}
} public class Cartoon extends Drawing{
Cartoon(){
System.out.println("Cartoon constructor");
} public static void main(String[] args) {
Cartoon x = new Cartoon();
}
}

运行输出如下:

Art constructor
Drawing constructor
Cartoon constructor

所以很容易发现,子类对象的构建过程是从父类"向外"扩散的,所以父类在子类构造器可以访问它之前,就已经完成了初始化。

上面的父类构造函数是没有参数的,如果父类只有一个带有参数的构造器,就必须在子类构造器中用关键字super显式的编写调用父类构造器的语句,否则编译器将无法找到符合'类名()'形式的构造器。

2、重载

重载是指不同的函数使用相同的函数名,但是函数的参数个数和类型不同。调用的时候根据函数的参数来区别不同的函数。在Java中,子类可以重载父类的方法。

//重载显示
class Homer{
char doh(char c) {
System.out.println("doh(char)");
return 'd';
} float doh(float f) {
System.out.println("doh(float)");
return 1.0f;
}
} class Milhouse{} class Bart extends Homer{
void doh(Milhouse m) {
System.out.println("doh(Milhouse)");
}
} public class Overload {
public static void main(String[] args) {
Bart b = new Bart();
b.doh(1);
b.doh('x');
b.doh(1.0f);
b.doh(new Milhouse());
} }

运行结果如下:

doh(float)
doh(char)
doh(float)
doh(Milhouse)

3、protected

在实际的项目中,经常会想要将某些事物尽可能对整个世界隐藏起来,但仍然允许子类的成员访问它们。关键字protected就起这个作用,它指明"就用户而言,这是private的,但对于任何继承于此类的子类,它是可以访问的“。

//Protected关键字的使用
class Villain{
private String name;
protected void set(String nm) {name = nm;}
public Villain(String name) {this.name = name;}
public String toString() {
return "I'm a Villain and my name is " + name;
}
} public class Orc extends Villain{
private int orcNumber;
public Orc(String name,int orcNumber) {
super(name);
this.orcNumber = orcNumber;
} public void change(String name,int orcNumber) {
set(name);
this.orcNumber = orcNumber;
} public String toString() {
return "Orc " + orcNumber + ": " + super.toString();
} public static void main(String[] args) {
Orc orc = new Orc("Z3",12);
System.out.println(orc);
orc.change("l4", 23);
System.out.println(orc);
}
}

运行结果如下:

Orc 12: I'm a Villain and my name is Z3
Orc 23: I'm a Villain and my name is l4

可以发现子类change()方法可以访问父类的set(),这是因为set()的访问修饰符是protected。

 参考文献:

[1]Java编程思想

Java基础 -- 复用类(组合和继承)的更多相关文章

  1. Java——代码复用(组合和继承)

    前言 "复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它必须还能够做更多的事情." Java解决问题都围绕类展开的, ...

  2. Java基础—复用类

    复用代码是Java众多引人注目的功能之一. 一般而言,实现代码重用java提供了两种方式:组合以及继承. 组合:新的类由现有类的对象所组成.(复用现有代码的功能,而非它的形式) 继承:按照现有类的类型 ...

  3. 【代码笔记】Java基础:类的继承(构造器)

    在Java中,创建对象的格式为: 类名 对象名 = new 类名(): 如: 1 JFrame jf = new JFrame(); 一个对象被创建出来时,经常要先做一些事这个对象才能正常使用,也可以 ...

  4. java基础/一个类A继承了类B,那么A就叫做B的派生类或子类,B就叫基类或超类。

    类重复,pulic class demo1 和class demo1 重复 无主类, 在cmd中输入命令: SET CLASSPATH=. (等号后为英文点符号),即可设置解释的路径为当前路径. 再次 ...

  5. 第二十九节:Java基础知识-类,多态,Object,数组和字符串

    前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...

  6. Java基础-StringBuffer类与StringBuilder类简介

    Java基础-StringBuffer类与StringBuilder类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringBuffer类 在学习过String类之后 ...

  7. 《Java基础——线程类》

    Java基础--线程类       一.线程的创建之Thread类: 规则: 通过声明一个新类作为子类继承 Thread 类,并复写 run() 方法,就可以启动新线程并执行自己定义的 run()方法 ...

  8. java基础-BigDecimal类常用方法介绍

    java基础-BigDecimal类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigDecimal类概述 我们知道浮点数的计算结果是未知的.原因是计算机二进制 ...

  9. java基础-BigInteger类常用方法介绍

    java基础-BigInteger类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigInteger类概述 Java中long型为最大整数类型,对于超过long ...

随机推荐

  1. WPF开源项目

    WPF有很多优秀的开源项目,我以为大家都知道,结果,问了很多人,其实他们不知道.唉,太可惜了! 先介绍两个比较牛逼的界面库 1.MaterialDesignInXamlToolkit Android风 ...

  2. TDBGridEh 标头排序

    数据源为adoQuery 1.首先设置dbGridEh里需要排序的字段的Title->Titlebutton属性为true 2.设置dgGridEh的optionsEh->dbhautoS ...

  3. Eclipse链接数据库

    在eclipse中找到数据库 选择数据库 然后点击next 填写数据库信息 选择需要执行的SQL语句 ALT+X 或者 右键点击execute selected text: 执行结果: 有问题请在评论 ...

  4. Hbase技术笔记

    一.Hbase介绍 二.Hbase的Region介绍 三.Hbase的写逻辑介绍 四.Hbase的故障恢复 五.Hbase的拆分和合并 如下ppt所示: 下面就来针对各个部分的内容来进行详细的介绍: ...

  5. kernel笔记——库文件与系统调用

    库文件 先从我们熟悉的c库入手,理解系统调用(system call).c代码中调用printf函数,经历了以下调用过程:   最终输出的功能由内核中write调用完成,c库封装了系统调用. 对于以下 ...

  6. MySQL之视图、触发器、事务、存储过程、函数

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  7. jenkins编译打包nodejs

    第一步 安装nodejs插件 第二步 在全局配置管理里面添加 nodejs配置 第三步 新建任务,从git上面拉取代码 cd /opt/tomcat7/bin/workspace/confdev #进 ...

  8. Python OpenCV 图像处理初级使用

    # -*- coding: utf-8 -*-"""Created on Thu Apr 25 08:11:32 2019 @author: jiangshan" ...

  9. .Net Core应用框架Util介绍(五)

    上篇简要介绍了Util在Angular Ts方面的封装情况,本文介绍Angular封装的另一个部分,即Html的封装. 标准组件与业务组件 对于管理后台这样的表单系统,你通常会使用Angular Ma ...

  10. 基于 HTML5 WebGL 的 3D 棉花加工监控系统

    前言 现在的棉花加工行业还停留在传统的反应式维护模式当中,当棉花加下厂的设备突然出现故障时,控制程序需要更换.这种情况下,首先需要客户向设备生产厂家请求派出技术人员进行维护,然后生产厂家才能根据情况再 ...