JAVA接口和抽象类

一、接口

1、接口的基本概念:

我们知道知道java中只支持单继承,但如果我们想定义一些功能,想让一个子类都继承实现,显然没办法做到,所有Java提供了接口这个概念,这样我们就可以用一个子类去实现多个接口。我们可以理解为接口就是特殊的抽象类

在java8后,接口可以包括数据成员,但是数据成员必须是常量,其值一旦被初始化后,是不允许修改的,这些数据成员通常为全局变量。

为了避免在接口中添加新方法后要修改所有的实现类,接口中允许定义默认方法(default方法)。

定义接口需要使用关键字interface.

interface A{            //定义一个接口
    public static final String MESSAGE="HelloWorld";        //全局常量
    public abstract void print();                                            //定义抽象方法
    default public void otherprint(){                                 //定义可以带方法体的默认方法
    System.out.println("默认方法");
    }
}

*注意:接口中成员属性默认是public static final修饰,成员方法是public abstact修饰,所以上述定义可以简写


interface A{            //定义一个接口
 
    String MESSAGE="HelloWorld";        //全局常量
 
    void print();                                            //定义抽象方法
 
    default void otherprint(){                                    //定义可以带方法体的默认方法
 
            System.out.println("默认方法");
 
    }
2、接口使用原则:

1.接口必须有子类,子类依靠implements关键字可以同时实现多个接口(用“,”隔开即可。);

2.接口的子类(如果不是抽象类)必须实现接口之中的全部抽象方法;

3.接口可以利用对象多态性,利用子类实现对象的实例化

4.接口和普通的类一样,本身也有数据成员和方法,但数据成员一定要初始赋值,并且此值不能再有修改,定义的方法可以有抽象方法和默认方法,抽象方法abstact关键字可以省略默认方法需要带上default关键字,默认方法可以带有方法体。

5.默认方法的调用和普通方法的调用一样

3、接口的使用:

我们来举个例子,定义一个抽象类People,一个普通子类Student,两个接口。子类Student继承父类People,并实现接口Study,Write

package demo;
//构建一个抽象类People
abstract class People{
	//父类属性私有化
	private String name;
	private int age;
	//提供父类的构造器
	public People(String name,int age){
		this.name = name;
		this.age = age;
	}
	//提供获取和设置属性的getter()/setter()方法
	public String getName() {
		return name;
	}
 
	public int getAge() {
		return age;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public void setAge(int age) {
		this.age = age;
	}
	
	//提供一个抽象方法
	public abstract void talk();	
}
 
//定义一个接口
interface Study{
	//设置课程数量为3
	int COURSENUM = 3;
	//构建一个默认方法
	default void stu(){
		System.out.println("学生需要学习"+COURSENUM+"门课程");
	}
}
 
//再定义一个接口
interface Write{
	//定义一个抽象方法
	void print();
}
 
//子类继承People,实现接口Study,Write
class Student extends People implements Study,Write{
	//通过super关键字调用父类的构造器
	public Student(String name, int age) {
		super(name, age);
	}
	//实现父类的抽象方法
	public void talk() {
		System.out.println("我的名字叫"+this.getName()+",今年"+this.getAge()+"岁");
	}
	//实现Write接口的抽象方法
	public void print() {
		System.out.println("学生会写作业");
	}
}
 
public class InterfaceDemo{
	public static void main(String[] args) {
		//构建student对象
		Student student = new Student("dodo", 22);
		//调用父类的抽象方法
		student.talk();
		//调用接口Write中的抽象方法
		student.print();
		//调用接口Study中的默认方法
		student.stu();
	}
}


二、抽象类

在讲抽象类之前有必要强调一下abstract修饰符:

  • abstract修饰的类为抽象类,此类不能有对象,(无法对此类进行实例化,说白了就是不能new);
  • abstract修饰的方法为抽象方法,此方法不能有方法体(就是什么内容不能有,包括{});

关于抽象类的使用特点:

  • 抽象类不能有对象,(不能用new此关键字来创建抽象类的对象);
  • 有抽象方法的类一定是抽象类,但是抽象类中不一定有抽象方法;
  • 抽象类中的抽象方法必须在子类中被重写。
java中抽象类和抽象方法到底有什么用呢?

你在做车的系统设计时,当你设计车这个通用类时,假如你确认别人实例化车这个通用类没有意义时(不知道是bike还是豪华轿车),你就坚决的在车这个通用类的类名前冠以abstract,将来就没人能实例化车这个类了。进一步讲:因为你不知道是什么车?所以你不知道如何驾驶,是拐把?还是方向盘?但你知道不管是什么车都得驾驶。所以你写个驾驶steer方法,冠以abstract,这样后来的子类,必须得把这个抽象方法实现掉。通过这种方法,你做架构设计的人就规定了后人的行为:必须得把驾驶这个抽象方法实现。

在Java语言中使用abstract class来定义抽象类。如下实例:

public abstract class Animal {
 public abstract void eat();
 public abstract void sleep();
}

以上代码是定义了一个叫做animal的抽象类,其中含有eat()和sleep()两个抽象方法。

定义了一个animal类之后再定义一个cat类:

public class Cat extends Animal{
 
	@Override
	public void eat() {
		System.out.println("我是猫,我吃的是猫粮呀");
		
	}
 
	@Override
	public void sleep() {
		System.out.println("我是猫,我比你们人类睡的时间短!");
		
	}

此时,我再来写一个Person类:

public class Person extends Animal {
 
	@Override
	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("我是人,我要吃大鱼大肉!!!");
	}
 
	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("我是人,每天必须睡够24个小时!!!!");
	}
}

三、抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其余代码
}

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

如果Salary类继承了Employee类,那么它必须实现computePay()方法:

public class Salary extends Employee
{
   private double salary; // Annual salary
  
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
 
   //其余代码
}

ps:

抽象类是指可以有抽象方法的类,言外之意就是它可以有不抽象的方法(继承:子类拥有父类非 private 的属性、方法)。
如果方法不加abstract,那它怎么知道谁是抽象方法谁不是?
而接口是抽象类的极端情况,接口不能有不抽象的方法,它的所有方法都要求也默认是抽象的,所以它不需要在方法前加abstract。


四、JAVA 接口和抽象类的区别

本质:从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范
区别:

  1. 接口的方法默认是public,所有方法在接口中不能有实现,抽象类可以有非抽象的方法
  2. 接口中的实例变量默认是final类型的,而抽象类中则不一定
  3. 一个类可以实现多个接口,但最多只能实现一个抽象类
  4. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定
  5. 接口不能用new实例化,但可以声明,但是必须引用一个实现该接口的对象
参数抽象类接 口
默认的方法实现可以有默认的方法实现完全抽象,根本不存在方法的实现
实现方式子类用extends关键字来继承抽象类,如果子类不是抽象类的话,它需要实现父级抽象类中所有抽象方法,父类中非抽象方法可重写也可不重写子类用implements去实现接口,需要实现接口中所有方法
构造器抽象类可以有构造器(构造器不能用abstract修饰)接口不能有构造器
与正常Java类的区别正常Java类可被实例化,抽象类不能被实例化,其他区别见上下文接口和正常java类是不同的类型
访问修饰符抽象方法可以用public、protected、default修饰接口默认是public、不能用别的修饰符去修饰
main方法抽象类中可以有main方法,可以运行它接口中不能有main方法,因此不能运行它
多继承抽象类可继承一个类和实现多个接口接口只能继承一个或者多个接口
速度抽象类比接口速度快接口稍微慢点,因为它需要去寻找类中实现的它的方法
添加新方法如果在抽象类中添加新非abstract的方法,可以直接添加,因为非abstract方法无需在子类中实现,如果是abstact方法,则需要改变子类的代码,也要实现这个方法只要在接口中添加方法,实现它的类就要改变,去实现这个新添加的方法
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值