构造器
- 仅当系统没有提供任何构造器时,系统才会提供默认构造器;
- 在构造器中,使用this调用另一个构造器:this()
- 在构造器中,使用super调用父类构造器:super()
构造器处理步骤
- 所有数据域被初始化为默认值(0、false或null);
- 按照类声明中出现的次序,依次执行所有域初始化语句和初始化块;
- 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体;
- 执行这个构造器主体;
JAVA类的访问修饰符
- private:仅对本类可见;
- public:对所有类可见;
- protected:对本包和所有子类可见;
- 默认(无修饰符):对本包可见
更改器方法与访问器方法
对实例域做出修改的方法被称为更改器方法(mutator method),仅访问实例域而不进行修改的方法被称为访问器方法(accessor method)
Class
- 静态嵌套类
- 内部类
- 局部类:方法内定义的类称为局部类
- 匿名内部类
- 匿名子类
匿名内部类
public static void main(String[] args) throws InterruptedException {
new Thread(getTask()).start();
}
private static Runnable getTask(){
return new Runnable() {
@Override
public void run() {
System.err.println("这是匿名内部类");
}
};
}
抽象类
- 任何包含一个或多个抽象方法的类都必须被声明为抽象的;
- 抽象类的所有子类,要么实现超类中的所有抽象方法,要么自己也声明为抽象的;
内部类与嵌套类的区别与联系
- 内部类的方法可以访问外部类的实例变量
- 当静态嵌套类的实例不需要知道它属于外部那个类的实例时,使用静态嵌套类;否则使用内部类;
- 静态的嵌套类只能通过对象访问外层包含类的非静态成员;也就是说嵌套类不能直接引用包含类的非静态成员变量;
- 内部类可以访问外部类的所有成员变量和方法;
- 内部类对象拥有一个对外部类对象的引用(outer);
- JavaSE8之前,必须把从局部类访问的局部变量声明为final;
匿名子类
ArrayList<String> list = new ArrayList<String>(100) {
public void add() {
super.add("hello");
}
};
ArrayList<String> list1 = new ArrayList<String>() {
{
add("heel");
}
};
静态内部类
- 在内部类不需要访问外部类对象的时候,应该使用静态内部类;
- 与常规内部类不同,静态内部类可以有静态域和方法;
- 声明在接口中的内部类自动成为static和public类;
类设计技巧
- 一定要保证数据私有;
- 一定要对数据初始化;
- 不是所有的域都需要独立的域访问器和域更改器
- 将职责过多的类进行分解
- 类名和方法名要能够体现它们的职责
- 优先使用不可变的类
知识点
- 在将超类转换为子类之前,应该使用instanceof进行检查;
- 在调用x.toString()的地方可以用"" + x代替
- instanceof(如果被检查对象为null,则结果返回false)
String str = null; if (str instanceof Object) { // 不产生异常result is false System.err.println("yes"); } System.err.println("no"); - 内部类不能声明静态成员;
public class ClassDemo { public static void main(String[] args) { System.err.println(ClassDemo.Student.num); System.err.println(ClassDemo.Teacher.code); } class Student { private final static int num = 10; // ok // private static int code = 10; // 编译报错 } static class Teacher { private static int code = 10; // ok } } 双括号初始化
public static void main(String[] args) throws Exception { init(new ArrayList<String>() { { add("luoyoub"); add("robert"); } }); } private static void init(List<String> list) { list.stream().forEach(System.err::println); }一个方法覆盖另一个方法时可以指定一个更严格的返回类型
class Student extends Person {
public Student get() {
return (Student) new Object();
}
}
class Person {
public Person get() {
return new Person();
}
}
Object
