- static final常量
- 必须声明同时初始化
- 通过类命点来访问,不能被改变
- 建议:常量名所有字母都大写,多个单词用下划线分隔
- 编译器在编译时会将常量直接替换为具体的值,效率高
- 类加载时,同时存在方法区中
- 抽象类:abstract ;注意:final是不可改变的,final修饰的方法不能被重写,而abstract是要求重写的,所以 abstract 和 final不能共存
- 封装共有的属性和行为------------------------代码复用
- 给所有派生类提供统一的类型---------------向上造型
- 可以包含抽象方法,为所有派生类提供统一的入口(造型后能点出来)派生类的具体实现不同,但入口是一致的
- 包含抽象方法的类必须是抽象类,不能被实例化,需要被继承
- 子类继承抽象父类:重写所有抽象方法
- 抽象类实例化只能走匿名内部类的形式,并且需要重写抽象方法
- 抽象方法:abstract
- 只有方法的定义,没有具体的实现
- 成员内部类:如果使用一个内部类 ,那么就可以省去在主类以外的再建一个类 ,内部类就是完成主类以外的那个类的作用
- 类中套类,外面的称为外部类,里面的称为内部类
- 内部类通常值服务于外部类,对外不具备可见性
- 内部类可以直接用其外部类的属性和方法
- 弥补了JAVA不能多继承的遗憾
- 内部类中可以直接访问外部类的成员(包括私有的),内部类中有个隐式的引用之相类创建它的外部类对象;语法:外部类名.this.
//成员内部类的演示
public class InnerClassDemo {
public static void main(String[] args) {
Mama m = new Mama();
//Baby b = new Baby(); //编译错误,内部类对外不具备可见性
//可以这么引用
Mama.Baby a = new Mama().new Baby();
}
}
class Mama{ //外部类
private String name;
void createBaby(){
Baby b = new Baby(); //正确
}
class Baby{ //内部类
void showMamaName(){
System.out.println(name);
System.out.println(Mama.this.name);
//System.out.println(this.name); //编译错误,this表示当前Baby类对象
}
}
}
- 匿名内部类:应用率高--------大大简化代码的操作
- 若想创建一个类(派生类对象),并且对象只被创建一次,此时该类不必命名,称为匿名内部类
- 即使用前提和条件:必须存在继承和实现关系的时候才可以使用
- 匿名内部类中不能修改外面变量的值,因为在匿名内部类中默认变量为final的
- 匿名内部类的三个步骤:
- 创建一个派生类,但没有名字
- 为该类创建了一个对象,名字为引用
- 大括号中的为派生类的类体
public class NstInnerClassDemo {
public static void main(String[] args) {
//1)创建了Aoo的一个派生类,但是没有名字
//2)为该派生类创建了一个对象,名为o1
//3)大括号中的为派生类的类体
Aoo o1 = new Aoo(){
};
//1)创建了Aoo的一个派生类,但是没有名字
//2)为该派生类创建了一个对象,名为o2
//3)大括号中的为派生类的类体
Aoo o2 = new Aoo(){
};
int num = 5;
//1)创建了Boo的一个派生类,但是没有名字
//2)给该派生类创建了一个对象,名为o3
//3)大括号中的为派生类的类体
Boo o3 = new Boo(){
void show(){
System.out.println("showshow");
//num = 55; //匿名内部类中不能修改外面变量的值,因为在此处变量会默认为final的
}
};
o3.show();
//或者
new Boo(){
void show(){
System.out.println("showshow");
//num = 55; //匿名内部类中不能修改外面变量的值,因为在此处变量会默认为final的
}
}.show();
//showshow
}
}
abstract class Boo{
abstract void show();
}
abstract class Aoo{
}
- 内部类有独立的.class嘛?有!
- 功能步骤:
- 若为某对象所特有的行为,则将方法设计在特定的类中
- 若为所有对象所共有的行为,则将方法设计在超类中
- 若为定时发生的,则在定时器中调用
Timer timer = new Timer(); //定时器对象
int intervla = 10; //定时的间隔,以毫秒为单位
//TimerTask 这个类里有一个抽象方法 run
//定时器任务 计划 安排 这里用匿名内部类 每10个毫秒自动执行
//第二个参数是从程序开始到执行的间隔
//第三个参数是以后每次执行的间隔
timer.schedule(new TimerTask() {
@Override
public void run() {
}
}, intervla, intervla);