目录
抽象类
为什么需要抽象类?如何定义抽象类?
- 是一种模板模式,抽象类为所有子类提供了一个通用模板,子类可以在这个模板基础上进行扩展。
- 通过抽象类,可以避免子类设计的随意性。通过抽象类,我们可以做到严格限制子类的设计,使子类之间更加通用。
abstract class Animal{
abstract void shout();
}
class Dog extends Animal{
void shout(){
...
}
}
要点
- 抽象方法和抽象类均必须用abstract来修饰。
- 抽象方法没有方法体,只需要声明不需要实现。
- 有抽象方法的类只能定义成抽象类。
- 抽象类里面的方法不一定全是抽象方法,也可能没有抽象方法。
- 抽象类可以包含属性、方法和构造方法。
- 抽象类不能实例化,即不能用new来实例化抽象类,只能用来被子类调用。
- 抽象类只能用来继承。
- 抽象方法必须被子类实现。抽象类的子类必须覆盖所有的抽象方法才能被实例化,否则还是抽象类。
接口
为什么需要接口?接口和抽象类的区别?
- 接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面的专业的实现了:规范和具体实现的分离。
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。
接口相关规则
- 接口中所有方法都是抽象的。
- 即使没有显式的将接口中的成员用public标识,也是public访问类型的。
- 接口中变量默认用public static final标识,所以接口中定义的变量就是全局静态常量。
- 可以定义一个新接口,用extends去继承一个已有的接口。
- 可以定义一个类,用implements去实现一个接口中所有的方法。
- 可以定义一个抽象类,用implements去实现一个接口中部分方法。
如何定义接口?
- 格式:
[访问修饰符] interface 接口名 [extends 父接口1,父接口2,…] {
常量定义; //总是public static final
方法定义; //总是public abstract
}
如何实现接口?
- 子类通过implements来实现接口中的规范。
- 接口不能创建实例,但是可用于声明引用变量类型。
- 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
- Java的类只支持单继承,接口支持多继承。
interface TestA{
void testA();
}
interface TestB{
void testB();
}
interface TestC extends TestA,TestB{
void testC();
}
class test implements TestC{
@Override
public void testA() {}
@Override
public void testB() {}
@Override
public void testC() {}
}
Java中,一个类只能继承一个类,但同时可以实现多个接口,即可以实现多重继承的效果和功能,也避免了多重继承的危险性。
内部类
内部类的作用
- 内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。
- 内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。但外部类不能访问内部类的内部属性。
使用场合
由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,通常内部类在只为所在外部类提供服务的情况下优先使用。
内部类的分类
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
成员内部类
可以使用private、protected、public任意进行修饰。类文件:外部类$内部类.class。外部类中使用非静态内部类和平时使用其他类没什么区别。
-
非静态内部类必须寄存在一个外部类对象中。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象。
-
非静态内部类可以使用外部类的成员,但是外部类不能直接访问非静态内部类成员。
-
非静态内部类不能有静态方法、静态属性和静态初始化块。
-
静态成员不能访问非静态成员:外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。
-
成员变量访问要点:
1)内部类里方法的局部变量:变量名
2)内部类属性:this.变量名
3)外部类属性:外部类名.this.变量名 -
内部类的访问:
public class InnerClassLen {
public static void main(String[] args){
Face face = new Face();
Face.Nose nose = face.new Nose();
nose.test();
}
}
class Face{
int age = 10;
class Nose{
int age = 20;
public void test(){
int age = 30;
System.out.println("test...");
System.out.println(Face.this.age);
System.out.println(this.age);
System.out.println(age);
}
private void test02(){
System.out.println("test02...");
}
}
}
静态内部类
定义方式
static class Eyes{
/**
* 类体
*/
}
使用要点
- 当一个静态内部类对象存在,并不一定存在对应的外部类对象。因此,静态内部类的实例方法不能直接访问外部类的实例方法。
- 静态内部类看做外部类的一个静态成员。因此,外部类的方法可以通过:静态内部类.名字 访问静态内部类的静态成员。通过 new 静态内部类() 访问静态内部类的实例。
class Face{
int age = 10;
static String name = "李四";
public void testStaticInnerClass(){
System.out.println(Eyes.name);
Face.Eyes eyes = new Face.Eyes();
System.out.println(eyes.address);
eyes.test03();
}
static class Eyes{
static String name = "张三";
String address = "China";
public void test03(){
String nameTemp = Face.name;
int ageTemp = new Face().age;
System.out.println("test03..." + nameTemp + " " + ageTemp);
}
}
}
方法内部类
定义在方法内部。作用域只限于本方法。
匿名内部类
适合那种只需要使用一次的类。比如:键盘监听操作等等。
要点
- 可以实现一个接口,或者继承一个父类。
- 只能实现一个接口。
- 适合创建那种只需要一次使用的类,不能重复使用。比较常见的是在图形界面编程GUI里用得到。
- 匿名内部类要使用外部类的局部变量,必须使用final修饰该局部变量。