9.1 抽象类和抽象方法
抽象类和抽象方法用abstract修饰,有抽象方法的类只能被定义为抽象类,抽象类可以没有抽象方法
-
含3类抽象方法必须定义为抽象类
直接定义抽象方法
继承一个抽象父类,但未完全实现抽象父类中的抽象方法
实现一个接口,但未完全实现接口包含的的抽象方法 -
抽象规则
- 抽象类不能创建对象,无法通过new调用抽象类构造函数创建抽象类
- 抽象类的构造器主要用来被子类调用
- 抽象方法只有方法签名,没有方法体
public abstract class shape{ //定义抽象类shape
private String color;
public abstract double getPerimeter();//定义抽象方法(获取周长)
public abstract String getType();//定义抽象方法(获取形状)
//构造器,主要用于创建子类对象时调用
public shape(){
}
public shape(String color){
this color = color;
}
}
//circle类继承自抽象类shape
public class circle extends shape{
private double radius;
public circle(String color,double radius){
super(color);//调用抽象类构造函数,初始化circle类
this.radius = radius;
}
//重写抽象函数
@Override
public double getPerimeter(double radius){
return 2 * Math.PI * radius;
}
//重写抽象函数
@Override
public String getType(){
return "圆形";
}
}
注意
- abstract修饰类时,表示该类只能被继承
- abstract修饰方法时,该方法需由子类重写
- final修饰的类不能继承,修饰的方法不能重写
- 不能调用static 和 abstract 同时修饰的方法无法调用没有方法体的方法
9.2 接口
接口是一种与类相似的结构,只包含常量和抽象方法
接口是一种特殊的类
每个接口被编译为独立的字节码文件
- 定义接口
修饰符 interface 接口名{
......
}
修饰符 interface 接口名 extends 接口名{
......
}
接口内容:
- 成员变量(只能是静态常量)
- 方法(抽象方法||类方法||默认方法(default修饰))
- 内部类(内部接口)
接口只能继承接口,可以多重继承
接口内所有成员访问类型定义为public
接口内的普通方法默认用public abstract修饰
接口内定义成员变量时
int a = 10;
等效于
public static final int a = 10;
===================================================
public interface output{
int a = 50; //默认定义格式 public static final int a = 50
void out(); //默认定义格式 public abstract void out();
void getData(String path);
default void print() { //接口内可以定义默认方法,用default修饰
System.out.println("Hallo");
}
static void statictest() { //接口内可以定义类方法,用static修饰
System.out.println("World");
}
}
不同包下,可以通过包名.接口名.成员变量(成员函数)进行访问(于类相似)
注意
一个JAVA源文件中最多只能有1个public接口,若JAVA源文件中定义了1个public接口,则文件名必须与接口名同名
9.3 接口的继承
接口可以多继承,各父类之间用,隔开
public class Test{
public static void main(String[] args) {
System.out.println(C.a);
System.out.println(C.b);
System.out.println(C.c);
}
}
interface A{
int a = 1;
}
interface B{
int b = 2;
}
interface C extends A,B{//接口C继承自父类A,B,获取了a,b,元素
int c = 3;
}
接口内的成员变量默认定义格式 public static final int a = 1,因此接口外可以访问
9.4 使用接口
implements关键字
修饰符 class 类名 extends 父类名 implements 接口1,接口2{
....
}
- 实现接口可获得接口中的变量,方法
- 接口中的方法为抽象方法,在类实现接口时必须重写接口的所有抽象方法(实现抽 象方法)
- 接口中的方法为默认方法,类中可以直接调用
- 实现类(子类)中重写接口(父类)方法时的访问权限必须相等或更大
(接口中方法为public权限,子类访问权限只能相等或更大)
public class Test{
public static void main(String[] args) {
D D1 = new D();
System.out.println(D1.dd+D1.d+D1.a+D1.b+D1.c);//直接调用D1的变量
D1.spellA();
D1.spellB();
D1.spellC();
D1.fly();//直接调用接口的默认函数
A A1 = new D();//类D对象引用可直接赋值给接口对象引用
Object obj = A1;//接口对象引用可直接赋值给Object类型的引用变量
}
}
//父类DD
class DD{
protected int dd = 5;
}
//子类D继承父类DD,实现接口C
class D extends DD implements C {
int d = 4;
@Override
public void spellA() {
System.out.println("A");
}
@Override
public void spellB() {
System.out.println("B");
}
@Override
public void spellC() {
System.out.println("C");
}
}
//接口A
interface A{
int a = 1;
void spellA();//抽象函数
default void fly() {//默认函数
System.out.println("飞!");
}
}
interface B{
int b = 2;
void spellB();
}
//接口C继承A,B
interface C extends A,B{
int c = 3;
void spellC();
}
A A1 = new A();
错误接口不能实例化
A A1 = new D();//A1实际上是1个只包含(a,fly(),spellA())的D类对象
相当于子类对象赋值给父类变量
Object obj = A1;//接口对象引用可直接赋值给Object类型的引用变量
Java中任何对象都是Object的实例
9.5 内部类
- 内部类可用private static protected修饰
非静态内部类
public class A{
...
private class B{
...
}
}
- 非静态内部类中可以直接访问外部类成员
调用非静态内部类方法>>>通过内部类对象>>>寄生于外部类实例 - 内部类访问变量次序
局部>内部类>外部类 - 内部类与外部类变量名重复的访问方式
外部类类名.this.外部类实例变量 - 外部类不能直接访问非静态内部类实例变量
- 内部类不一定存在
- 通过创建内部类对象去访问
- 非静态内部类对象必须寄生在外部类对象里
public class practice{
private int age;
public practice() {
}
public practice(int age) {
this.age = age;
}
//内部类
private class man{
private String name;
public man() {
}
public man(String name) {
this.name = name;
}
public void printMan(){
System.out.println(name);
System.out.println(age);//内部类可以直接调用外部类的成员变量
}
}
//外部类测试函数
public void test() {
man m = new man("赵文耀");//外部类中创建1个内部类对象
m.printMan();//调用内部类对象的函数
}
//外部类主函数
public static void main(String[] args) {
practice p = new practice(19);//创建外部类对象
p.test();//调用外部类测试函数
}
}
编译上面程序,bin目录里出现2个.class文件
- 内部类.class文件
- 外部类.class文件
外部类的静态成员无法访问非静态内部类
public class practice{
private class bb{}
public static void main(String[] args) {
new bb();//错误
}
}
静态内部类中不能定义静态成员
public class B{
private class b{
static {}//错误
private static int a;//错误
private static void test() {};//错误
}
}