JavaSE 抽象类与接口

一、抽象类

1. 抽象类概述

  • 类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类;类本身是不存在的,所以抽象类无法创建对象(即无法实例化)
  • 抽象类属于引用数据类型
  • 基础语法格式:
[修饰符列表] abstract class 类名{
		类体;
}
  • 抽象类是无法实例化的,无法创建对象的,所以抽象类是用来被子类继承的,子类继承后可以实例化对象,另外,抽象类的子类可以是抽象类,也可以是非抽象类;虽然抽象类无法实例化,但是抽象类有构造方法,这个构造方法可以供子类使用
  • final 和 abstract 不能联合使用,这两个关键字是对立的, 因为抽象类必须被继承才能使用,而且必须重写所有的抽象方法,但是被 final 修饰则不能被继承与重写
  • 非抽象子类继承抽象父类时,必须重写父类的抽象方法

2. 抽象方法

  • 抽象方法表示没有实现的方法,没有方法体的方法
  • 特点:
    没有方法体,以分号结尾
    前面修饰符列表中有abstract关键字
  • 抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中

3. 面向抽象编程

  • 面向抽象(接口)编程,不面向具体编程,降低程序的耦合度,提高程序的扩展力,符合OCP原则(对扩展开放,对修改关闭)

4. 面试题

  • Java中凡是没有方法体的方法都是抽象方法?
    错误,Object类中就有很多方法没有方法体,都是以“;”结尾的,但它们都不是抽象方法,如:public native int hashCode(); 这个方法底层调用了C++写的动态链接库程序,前面修饰符列表中没有:abstract,有native,表示调用JVM本地程序

二、接口

1. 接口概述

  • 接口是一种引用数据类型,由 interface关键字修饰,并且是完全抽象的(特殊的抽象类)

2. 接口的基础语法

[修饰符列表] interface 接口名{}
  • 接口支持多继承,一个接口可以继承多个接口
  • 接口中只包含两部分:常量与抽象方法(即接口里面的变量都是常量,所以public static final可以省略;接口里面的方法都是抽象方法,所以接口中的方法不能有方法体)
  • 接口中定义行为,抽象类中定义属性和(非)抽象方法
  • 接口中所有的元素都是public修饰的(都是公开的)
  • 接口中的抽象方法定义时:public abstract修饰符可以省略
public class Test01 {
	public static void main(String[] args) {
		// 访问接口的常量。
		System.out.println(D.PI);
		// 常量不能二次赋值
		// D.PI = 3.1415928;
	}
}

// 定义接口
interface A {

}

// 接口支持继承
interface B extends A {

}

// 接口支持多继承(一个接口可以继承多个接口)
interface C extends A, B {
}

// 定义接口
interface D{
	// 常量
	// public static final double PI = 3.1415926; 
	// public static final可以省略
	double PI = 3.1415926;

	// 接口中随便写一个变量就是常量(省略了 public static final)
	int k = 100;

	// 抽象方法
	// public abstract int sum(int a, int b);
	// public abstract可以省略
	int sum(int a, int b);

	// 接口中的方法不能有方法体
	// 错误:Abstract methods do not specify a body
	/*
	 * void M() {
		
	}
	 */
	// 相减的抽象方法
	int sub(int a, int b);
}
  • 类和类之间、接口和接口之间叫做继承(继承使用extends关键字完成),类和接口之间叫做实现(实现使用implements关键字完成)
  • 当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部重写
  • 一个类可以同时实现多个接口,Java中的接口弥补了单继承带来的缺陷
  • 接口和接口之间在进行强制类型转换的时候,没有继承关系,也可以强转,但运行时有可能会出现ClassCastException异常,所以需要加:instanceof运算符进行判断
public class Test01 {
	public static void main(String[] args){
		// 多态:父类型引用指向子类型对象
		A a = new D();
		//a.m2(); // 编译报错。A接口中没有m2()方法
		B b = new D();
		C c = new D();

		// 调用其他接口中的方法,需要转型(接口转型)
		B b2 = (B)a;
		b2.m2();

		// 也可以直接向下转型为D
		D d = (D)a;
		d.m2();

		M m = new E();
		// 经过测试:接口和接口之间在进行强制类型转换的时候,没有继承关系,也可以强转
		// 但是运行时可能会出现ClassCastException异常
		// 编译没问题,运行有问题。
		//K k = (K)m;
		if(m instanceof K){
			K k = (K)m;
		}
	}
}


interface K{
}
interface M{
}
class E implements M{
}


interface X{
}
interface Y{
}
//接口和接口支持多继承
interface Z extends X,Y{
}


interface A{
	void m1();
}
interface B{
	void m2();
}
interface C{
	void m3();
}
// 一个类实现多个接口
class D implements A,B,C{
	// 实现A接口的m1()
	public void m1(){
		
	}
	// 实现B接口中的m2()
	public void m2(){
		System.out.println("m2 ....");
	}
	// 实现接口C中的m3()
	public void m3(){
	
	}
}
  • 如果继承和实现都存在,则extends 关键字在前,implements 关键字在后
public class Test01 {
	public static void main(String[] args){
		// 创建对象
		// 多态
		Flyable f = new Cat();
		f.fly();
	}
}
class Animal{
}

// 接口通常提取的是行为动作
interface Flyable{
	void fly();
}

// 动物类子类:猫类
class Cat extends Animal implements Flyable{
	public void fly(){
		System.out.println("飞猫");
	}
}
  • 使用接口时,可以使用多态

3. 接口的作用

  • 解耦合(接口可以将调用者和实现者解耦合)
    面向接口编程,可以降低程序的耦合度,提高程序的扩展力,符合OCP开发原则(对扩展开放,对修改关闭)
    接口的使用离不开多态机制(接口+多态才可以达到降低耦合度)
    调用者面向接口调用
    实现者面向接口编写实现
    大项目的开发,一般都是将其分离成一个模块一个模块的,模块和模块之间采用接口衔接,降低耦合度

三、类和类之间的关系

  • is a(继承)、have(has) a(关联)、like a(实现)
  • is a:
    Cat is a Animal(猫是一个动物),凡是能够满足is a的表示“继承关系”
    A extends B
public class A {
}
public class B extends A {
}
public interface C {
}
public interface D extends C {
}
  • have(has) a:
    I have a Pen(我有一支笔),凡是能够满足have(has) a关系的表示“关联关系”,关联关系通常以“属性”的形式存在,一个类可以知道另一个类的属性和方法,在 Java 语言中使用成员变量体现
public class A {
 private B b;
}
public class B {
}
  • like a:
    Cooker like a FoodMenu(厨师像一个菜单一样),凡是能够满足like a关系的表示“实现关系”,实现关系通常是:类实现接口
    A implements B
public interface E {
}
public class F implements E {
}

四、抽象类和接口的区别

  • 抽象类是半抽象的,接口是完全抽象的
  • 抽象类中有构造方法,接口中没有构造方法
  • 接口和接口之间支持多继承,类和类之间只能单继承
  • 一个类可以同时实现多个接口,但只能继承一个类
  • 接口中只允许出现常量和抽象方法
  • 接口使用的比抽象类多,接口一般都是对“行为”的抽象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jayco江柯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值