9. 抽象类与接口

9.1 抽象类和抽象方法

抽象类和抽象方法用abstract修饰,有抽象方法的类只能被定义为抽象类,抽象类可以没有抽象方法

  • 含3类抽象方法必须定义为抽象类

    直接定义抽象方法
    继承一个抽象父类,但未完全实现抽象父类中的抽象方法
    实现一个接口,但未完全实现接口包含的的抽象方法

  • 抽象规则

  1. 抽象类不能创建对象,无法通过new调用抽象类构造函数创建抽象类
  2. 抽象类的构造器主要用来被子类调用
  3. 抽象方法只有方法签名,没有方法体
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 接口名{
		......
}

接口内容:

  1. 成员变量(只能是静态常量)
  2. 方法(抽象方法||类方法||默认方法(default修饰))
  3. 内部类(内部接口)

接口只能继承接口,可以多重继承
接口内所有成员访问类型定义为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.外部类实例变量
  • 外部类不能直接访问非静态内部类实例变量
  1. 内部类不一定存在
  2. 通过创建内部类对象去访问
  • 非静态内部类对象必须寄生在外部类对象里
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() {};//错误
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43498251/article/details/88065234