[7]复用类 0X01
2016-07-25 14:42
429 查看
复用代码的两种方式:
1.组合
2.继承
类中域的基本数据类型能够自动被初始化为”零”,但是对象引用会被初始化为null,如果这时你试图为他们调用任何方法,都会得到一个空指针异常。然而,在不抛出异常的情况下,仍旧可以打印一个null引用。
初始化引用的位置:
1.在定义对象的地方,意味着它们总是能够在构造器被调用之前初始化。
2.在类的构造器中。
3.使用实例初始化。
4.“惰性初始化”、就在正要使用这些对象之前。(在生成对象不值得及
不必每次都生成对象的情况下,这种方式可以减少额外的负担)
上代码,演示四种方式:
OutPuts:
java会自动在子类的构造器中插入对基类构造器的调用,下面的代码展示了上述机制在三层继承关系上是如何工作的:
可以看到,对于构造器的调用是从基类“向外”扩散的,所以基类在子类构造器可以访问它之前,就已经完成了初始化。即使你不为Cartoon()创建构造器,编译器也会为你合成一个默认的构造器,该构造器将调用基类的构造器。
1.1下面的我们来证明基类构造器总是会被调用,并且在子类构造器之前被调用:
从打印的结果可以看出,结论是成立的。
2.带参数的构造器
如果一个类的基类没有默认的构造器,或者想调用一个带参数的基类构造器,就必须用关键字super显示地编写调用基类构造器的语句,并且配以适当的参数列表:
如果不在BoardGame()中显示的调用基类构造器,编译器会出错误提示;而且,调用基类构造器是你在子类中应该做的第一件事情。
1.组合
2.继承
每一个非基本类型的对象都有一个toString()方法。
组合
1.引用的初始化:类中域的基本数据类型能够自动被初始化为”零”,但是对象引用会被初始化为null,如果这时你试图为他们调用任何方法,都会得到一个空指针异常。然而,在不抛出异常的情况下,仍旧可以打印一个null引用。
初始化引用的位置:
1.在定义对象的地方,意味着它们总是能够在构造器被调用之前初始化。
2.在类的构造器中。
3.使用实例初始化。
4.“惰性初始化”、就在正要使用这些对象之前。(在生成对象不值得及
不必每次都生成对象的情况下,这种方式可以减少额外的负担)
上代码,演示四种方式:
package me.funnyzhao.recycleclass; class Soap{ private String s; Soap(){ //构造器中初始化 System.out.println("Soap()"); s="Constructed"; } @Override public String toString(){ return s; } } public class Bath { //在定义对象的地方初始化 private String s1="Happy", s2="Happy", s3,s4; private Soap catille; private int i; private float toy; public Bath(){ System.out.println("Inside Bath()"); s3="joy"; toy=3.14f; catille=new Soap(); } { //在所有初始化前调用 i=47; System.out.println(i); } @Override public String toString() { //惰性初始化 if(s4==null){ s4="joy"; } return "s1="+s1+"\n"+ "s2="+s2+"\n"+ "s3="+s3+"\n"+ "s4="+s4+"\n"+ "i="+i+"\n"+ "toy="+toy+"\n"+ "castille= "+catille; }; public static void main(String[] args) { Bath b=new Bath(); System.out.println(b); } }
OutPuts:
47 Inside Bath() Soap() s1=Happy s2=Happy s3=joy s4=joy i=47 toy=3.14 castille= Constructed
继承
1.初始化基类java会自动在子类的构造器中插入对基类构造器的调用,下面的代码展示了上述机制在三层继承关系上是如何工作的:
class Art{ Art(){Sytem.out.println("Art Cr")} } class Drawing extends Art{ Drawing(){ System.out.println("Deawing Cr"); } } public class Cartoon extends Drawing{ public Cartoon(){System.out.println("Cartoon Cr");} public static void main(String[] args){ Cartoon x=new Cartoon(); } } /* output: Art Cr Drawing Cr Cartoon Cr */
可以看到,对于构造器的调用是从基类“向外”扩散的,所以基类在子类构造器可以访问它之前,就已经完成了初始化。即使你不为Cartoon()创建构造器,编译器也会为你合成一个默认的构造器,该构造器将调用基类的构造器。
1.1下面的我们来证明基类构造器总是会被调用,并且在子类构造器之前被调用:
class Soap{ Soap(){ System.out.println("Soap()"); } } public class Bath extends Soap{ static{ System.out.println("static域"); } { System.out.println("空白"); } Bath(){ System.out.println("Bath"); } Bath(int i){ System.out.println("Bath"+i); } public static void main(String[] args) { new Bath(1); new Bath(2); } } /*output: static域 Soap() 空白 Bath1 Soap() 空白 Bath2 */
从打印的结果可以看出,结论是成立的。
2.带参数的构造器
如果一个类的基类没有默认的构造器,或者想调用一个带参数的基类构造器,就必须用关键字super显示地编写调用基类构造器的语句,并且配以适当的参数列表:
class Game{ Game(int i){ System.out.println("Game()"); } } class BoardGame extends Game{ BoardGame(int i) { super(i); System.out.println("BoardGame()"); } } public class Bath extends BoardGame { Bath(){ super(11); System.out.println("Bath()"); } public static void main(String[] args) { Bath c=new Bath(); } } /*output: Game() BoardGame() Bath() */
如果不在BoardGame()中显示的调用基类构造器,编译器会出错误提示;而且,调用基类构造器是你在子类中应该做的第一件事情。
相关文章推荐
- Java基础教程之组合(composition)
- C#实现排列组合算法完整实例
- php通过排列组合实现1到9数字相加都等于20的方法
- 深入理解JAVA中的聚集和组合的区别与联系
- C语言实现的阶乘,排列和组合实例
- C++中继承与组合的区别详细解析
- SQL语句实现表中字段的组合累加排序
- python以环状形式组合排列图片并输出的方法
- PHP组合查询多条件查询实例代码第1/2页
- JavaScript如何实现组合列表框中元素移动效果
- IOS设计模式之组合设计模式
- C++中的继承和组合区别使用
- SQL语句实现表中字段的组合累加排序
- 类的继承与派生
- 递归法解组合问题
- 再探java基础——对面向对象的理解(2)
- 排列&组合
- 允许重复选取的组合数
- C++ 全排列和组合算法(递归)
- 字符所有组合