一、继承与清理

  如果某个类需要去清理自身的资源,那么必须用心为其创建回收垃圾的方法,而如果此类有导出的子类,那么必须在导出类中覆盖回收的方法,当覆盖被继承类的回收垃圾的方法的时候,需要注意销毁的顺序应该和初始化的顺序相反。对于字段来说,意味着与声明的顺序相反。应该先对导出类进行清理,然后才是基类。这是因为导出类的清理可能会调用基类的某些方法,所以需要使基类的构件仍起作用而不应过早的销毁他们。

  如果需要去销毁被多个成员对象共享的变量的时候,这种情况会变得很复杂。这种情况下,可以使用引用计数法来跟综访问着共享对象的代码数量,代码如下:

import static net.mindview.util.Print.*;
class Shared {
private int refcount=0; //标识引用该变量的个数
private static long counter=0;
private final long id=counter++; //标识Shared变量
public Shared() {
print("Creating "+this);
}
public void addRef() {
refcount++;
}
protected void dispose() {
if(--refcount==0) {
print("Disposing "+this);
}
}
public String toString() {
return "Shared"+id;
}
}
class Composing {
private Shared shared;
private static long counter=0;
private final long id=counter++;
public Composing(Shared shared) {
print("Creating "+this);
this.shared=shared;
this.shared.addRef();
}
protected void dispose() {
print("disposing "+this);
shared.dispose();
}
public String toString() {
return "Composing"+id;
}
}
public class ReferenceCounting { public static void main(String[] args) {
Shared shared=new Shared();
Composing[] composing={new Composing(shared),new Composing(shared),
new Composing(shared),new Composing(shared)};
for(Composing c:composing) {
c.dispose();
}
} }

二、构造器内部的多态方法的行为

  如果调用构造器内部的一个动态绑定的方法的时候,就需要用到那个方法被覆盖后的定义,动态绑定的方法调用导出类的方法,此时导出类成员变量还未被初始化,可能会产生错误。

public class Test {
public static void main(String[] args) {
new NewSon().print();
}
}
abstract class Father {
String fs="Dad!";
public Father() {
print();
}
public abstract void print();
}
class NewSon extends Father {
int i=4;
String ss="son!";
public void print() {
System.out.println("Son.."+i);
// System.out.println(ss.toUpperCase()); error
}
}

  小细节:如果一个类实现了一个接口,同时继承了另外一个类,如果被继承的类有和接口中同样方法签名的方法,那么子类可以不用提供对于方法的实现。父类继承过来的方法相当于在子类中实现了接口。

interface Eat {
public void eat();
}
class Dog {
public void eat() { }
}
public class BadDog extends Dog implements Eat {}

、内部类的一些细节

  1.如果在内部类生成对外部类的引用,可以通过外部类的名字加上.this,这样产生的引用会自动具有正确的开销.但是.this只能在外部类内部和内部类使用,其他类里不能使用.

  2.在匿名内部类中,如果基类需要一个有参数的构造器,也可以传递参数给基类的构造器,代码如下:

class Wrapping {
private int i;
public Wrapping(int x) {
i=x;
}
public int value() {
return i;
}
}
class Parcel8 {
public Wrapping wrapping(int x)/*传入基类构造器*/ {
return new Wrapping(x) {
public int value() {
return 47*super.value();
}
};
}
}

  3.接口中也可以声明内部类,接口中的内部类自动被声明为public 和 static的类型,甚至可以在内部类中实现外部接口.

interface Dog {
public void bark();
class GoodDog implements Dog { @Override
public void bark() {
System.out.println("bark!");
} }
}

  4.在继承内部类的时候,指向外围类的秘密的引用必须也要被初始化,因此使用特殊的语法来明确说明这种关联:

class WithInner {
class Inner{
int i=0;
public Inner (int i) {
this.i=i;
}
}
}
class InheritInner extends WithInner.Inner { public InheritInner(WithInner withInner, int i) {
withInner.super(i);
} }

  5.当继承外部类的时候。内部类并没有什么变化,两个内部类完全是独立的个体,各自在各自的命名空间内。

四、为什么需要内部类

  1.每个内部类都能独立的继承自一个接口的实现,无论外部类继承了什么类对于内部类没有任何影响。而由于内部类也可以使用外部类的成员,因此,内部类有效的实现了“多重继承”。

class GrandFather {
protected int gf=3;
}
class Father extends GrandFather {
protected int ft=2;
class Son extends Father {
protected int s=1;
public void say() {
System.out.println(gf+" "+ft+" "+s);
}
}
}

  2.利用内部类实现命令模式。

  可以将命令模式中的命令类放入调用者的内部来实现命令模式,代码如下:

public class Test4 {
public static void main(String[] args) {
GreenHouseControl gh=new GreenHouseControl();
gh.new LightOn().execute();
gh.new LightOff().execute();
gh.new WaterOn().execute();
gh.new WaterOff().execute();
}
}
interface Command /*命令接口*/{
public void execute();
}
class GreenHouseControl {
private boolean light=false;
class LightOn implements Command { @Override
public void execute() {
System.out.println("The light is on.");
light=true;
} }
class LightOff implements Command { @Override
public void execute() {
System.out.println("The light is off.");
light=false;
} }
private boolean water=false;
class WaterOn implements Command { @Override
public void execute() {
System.out.println("The water is on");
water=true;
} }
class WaterOff implements Command { @Override
public void execute() {
System.out.println("The water is off");
water=false;
} }
}

  对于内部类的知识原理性整理可参见:http://www.cnblogs.com/hlhdidi/p/5575607.html     http://www.cnblogs.com/hlhdidi/articles/5575416.html

Java编程思想学习笔记_3(继承,内部类)的更多相关文章

  1. Java编程思想学习笔记_2(继承和多态)

    静态初始化: 静态初始化只在必要的时刻进行.(即当程序需要加载类进入内存的时候,执行静态初始化.静态变量和静态代码块的初始化顺序,按照在代码中声明的顺序老执行.例如:如果要执行某个public类,那么 ...

  2. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  3. Java编程思想 学习笔记10

    十.内部类  可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性.然而必须要了解,内部类和组合是 ...

  4. 《Java编程思想》笔记 第十章 内部类

    1.创建内部类对象 创建内部类对象(相当于new内部类对象) 外围类对象.new 内部类( ). 创建内部类对象一种方法是 外围类有一个方法返回内部类对象. 没有外围类对象就不能创建内部类对象,因为内 ...

  5. Java编程思想 学习笔记1

    一.对象导论 1.抽象过程 Alan Kay曾经总结了第一个成功的面向对象语言.同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这些特性表现了纯粹的面向对象程序设计方式 1)万物皆 ...

  6. [Java编程思想-学习笔记]第1章 对象导论

    1.1  抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...

  7. Java编程思想 学习笔记11

    十一.持有对象  通常,程序总是根据运行时才知道的某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型. Java实用库还提供了一套相当完整的容器类来解决这个问题,其中基本的类 ...

  8. Java编程思想学习笔记——类型信息

    前言 运行时类型信息(RTTI:Runtime Type Information)使得我们可以在程序运行时发现和使用类型信息. Java在运行时识别对象和类的信息的方式: (1)一种是RTTI,它假定 ...

  9. Java编程思想 学习笔记12

    十二.通过异常处理错误  Java的基本理念是“结构不佳的代码不能运行”. Java中的异常处理的目的在于通过使用少于目前数量的代码来简化大型.可靠的程序的生成,并且通过这种方式可以使你更加自信:你的 ...

随机推荐

  1. java面试每日一题9

    题目:判断一个数是否是2的方次幂 public class Power { public static void main(String [] args) throws NumberFormatExc ...

  2. 【转】MYSQL入门学习之九:索引的简单操作

    转载地址:http://www.2cto.com/database/201212/176772.html 一.创建索引  www.2cto.com           MYSQL常用的索引类型主要有以 ...

  3. java中@value的环境配置

    @value 在现阶段我想大家对注解都不陌生,@value的用法就是在后台获取配置文件的信息,从而方便修改一些固定的配置.不明白的可以百度@value的详解. 配置@value有以下几个步骤. 1.首 ...

  4. 使用KNN对MNIST数据集进行实验

    由于KNN的计算量太大,还没有使用KD-tree进行优化,所以对于60000训练集,10000测试集的数据计算比较慢.这里只是想测试观察一下KNN的效果而已,不调参. K选择之前看过貌似最好不要超过2 ...

  5. ural 1109,NYOJ 239,匈牙利算法邻接表

    NYOJ 239:http://acm.nyist.net/JudgeOnline/problem.php?pid=239 ural 1109 :http://acm.timus.ru/problem ...

  6. hiho(1081),SPFA最短路,(非主流写法)

    题目链接:http://hihocoder.com/problemset/problem/1081 SPFA求最短路,是不应-羁绊大神教我的,附上头像. 我第一次写SPFA,我用的vector存邻接表 ...

  7. 用re-sign.jar重签名apk后安装失败的解决办法

    问题 打开re-sign.jar,将下载好的apk拖入re-sign.jar的界面进行重签名.重签名成功后,通过adb intall命令安装重签名后的apk文件失败.提示:Failure [INSTA ...

  8. Keytool生成csr

    一. 首先生成密钥库 keytool -genkey -keyalg RSA -keysize 4096 -keystore c:\keystore4096.jks 二.生成csr keytool - ...

  9. HDU 2289 CUP 二分

    Cup Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  10. CodeForces 471C MUH and House of Cards

    MUH and House of Cards Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & % ...