读书笔记:
标签类含义
通过一个枚举类的形式定义标签,管理实例的不同逻辑处理的分发控制。举个例子,内部枚举对象 Shape 表示图形的类型,计算面积的时候,通过标签类型分别选择圆形和矩形的计算方式来计算。
// Tagged class - vastly inferior to a class hierarchy!
class Figure {
enum Shape { RECTANGLE, CIRCLE };
// Tag field - the shape of this figure
final Shape shape;
// These fields are used only if shape is RECTANGLE
double length;
double width;
// This field is used only if shape is CIRCLE
double radius;
// Constructor for circle
Figure(double radius) {
shape = Shape.CIRCLE;
this.radius = radius;
}
// Constructor for rectangle
Figure(double length, double width) {
shape = Shape.RECTANGLE;
this.length = length;
this.width = width;
}
double area() {
switch(shape) {
case RECTANGLE:
return length * width;
case CIRCLE:
return Math.PI * (radius * radius);
default:
throw new AssertionError(shape);
}
}
}
这样做的缺点有哪些?
如何优化呢?
// Class hierarchy replacement for a tagged class
abstract class Figure {
abstract double area();
}
class Circle extends Figure {
final double radius;
Circle(double radius) { this.radius = radius; }
@Override double area() { return Math.PI * (radius * radius); }
}
class Rectangle extends Figure {
final double length;
final double width;
Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override double area() { return length * width; }
}
class Square extends Rectangle {
Square(double side) {
super(side, side);
}
}
先解释下几种嵌套类的类型
public class Main{
public static class NestClass{}
}
//在外面使用时候形式如下,在Main中使用则不需要加上外部类限定
Main.NestClass nestClass = new Main.NestClass();
public class Main{
// 静态和非静态的之前唯一的区别是,静态成员类的声明中包含static
public class MemberClass{}
}
不能
定义静态初始化代码块(Static Initializer)不能
在匿名类里面定义接口不能
在匿名类里面定义接口// 匿名类示例
public class Test {
public void test() {
Runnable r = new Runnable(){
@Override
public void run(){
System.out.println("hello");
}
};
}
}
// 非法语法:不能定义静态初始化代码块(Static Initializer)
public class A {
public void test() {
Runnable r = new Runnable() {
static { System.out.println("hello"); }
@Override
public void run() {
}
};
}
}
// 非法语法:不能在匿名类里面定义接口
public class A {
public void test() {
Runnable r = new Runnable() {
public interface Hello { };
@Override
public void run() {
}
};
}
}
// 非法语法:不能在匿名类中定义构造函数
public class A {
public void test() {
Runnable r = new Runnable() {
public Runnable() { }
@Override
public void run() {
}
};
}
}
public class Test {
{
class AA{}//块内局部类
}
public Test(){
class AA{}//构造器内局部类
}
public void test(){
class AA{}//方法内局部类
}
}
//注意到了吧,可以同名,编译后,形成诸如:外部类名称+$+同名顺序+局部类名称
//Test$1AA.class/Test$2AA.class/Test$3AA.class
非静态类使用有哪些问题呢?
// Typical use of a nonstatic member class
public class MySet<E> extends AbstractSet<E> {
... // Bulk of the class omitted
@Override
public Iterator<E> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<E> {
...
}
}
enclosingInstance.new MemberClass(args)
手动建立关联。正如你所预料的那样,该关联在非静态成员类实例中占用了空间,并为其构建添加了时间开销。那么如何使用更好呢?
如果你声明了一个不需要访问宿主实例的成员类,总是把 static 修饰符放在它的声明中,使它成为一个静态成员类,而不是非静态的成员类。