浅谈接口,抽象类(基础分析向)

接口

接口是什么?

用 interface 关键字定义的一个只有方法名,没有方法体的一个域就是接口。
当我们要实现接口的功能时,我们需要用到 implement 关键字。

为什么要用接口?
我们在工程里面会遇到这样的难题,有很多类都需要一个相同的方法或者变量,如果要相互调用非常麻烦,我们需要去实例化,或者继承关系或者抽象成抽象类等等等,但是如果定义成一个接口,那么所有的类都可以使用它并且还可以写入合适的方法。

接口的特征有哪些呢???

  • 不能使用new操作符去创建对象
  • 实现类必须重写接口的所有方法,反之,就将该实现类定义为一个抽象类
  • 类可以继承多个接口,多继承
  • 接口当中成员变量都是public static final,成员方法都是public
  • 接口当中的方法都是只有方法的声明而没有方法体
  • java8(jdk1.8)之后新添加的两个特性
  • default关键字可以定一个default方法,有方法的实现
  • 可以定义static的静态方法,有方法的实现

现在我们来实现一下:

interface InterfaceName1{ //接口一
    int index = 0;//默认修饰符为public static final

    public void func(); //接口的方法只能有方法名,不能有方法体

    public default void run(){  //JDK1.8之后的特性,可以有方法体的方法,但必须用default去修饰
	 System.out.println("新特性方法")}

    public static int getVaule(){ //1.8新特性,可以有静态方法
        return 1;
    }
}

interface InterfaceName2{ //接口二
    int index = 0;//默认修饰符为public static final

    public void func();

}

class A implements InterfaceName1, InterfaceName2{ //接口特性:多实现
    @Override
    public void func() {
        //System.out.println(index);
    }
}

我们现在可以发现一个问题,func()方法中打印的 index 到底是接口一还是接口二的??
这就是static关键字的用处了,我们可以直接用接口名去实现
在这里插入图片描述

并且接口是可以作为参数使用的
我们现在把接口作为参数,实现加减乘除功能。

interface Caculator{ //计算器接口
    public int caculate(int first, int secnd); //加 减乘除都是两个数做运算
}

//实现加法
class Add implements Caculator {  //用一个类实现这个接口的方法

    @Override
    public int caculate(int first, int secnd) {
        return first + secnd;
    }
}

//实现减法
class Sub implements Caculator{

    @Override
    public int caculate(int first, int secnd) {
        return first - secnd;
    }
}

//实现乘法
class Mul implements Caculator{

    @Override
    public int caculate(int first, int secnd) {
        return first * secnd;
    }
}

//实现除法
class Div implements Caculator{

    @Override
    public int caculate(int first, int second) {
        if(second == 0){
            return -1;
        }
        return first/second;
    }
}

public static void caculate1(Caculator ca, int first, int secend){  //把接口定义成参数,
																	//因为我们无法去实例化一个接口,
																	//所以我们必须要实例化实现接口的类
		System.out.println( ca.caculate(first,secend)) ; // 调用具体类实现的接口种的方法
		 }
public static void main(String[] args){
	 caculate1(new Add() , 12,12); //第一个参数我们实例化实现接口的类
        caculate1(new Sub() , 12,12);
        caculate1(new Mul() , 12,12);
        caculate1(new Div() , 12,12);
}

结果:
在这里插入图片描述

抽象类

抽象类是什么?

abstract 关键字修饰的方法叫做抽象方法,包含抽象方法的的类叫做抽象类,并且该类必须用abstract关键字修饰

为什么要用到抽象类??
无法实现具体方法,需要多态(继承,重写,向上转型)
例如,一个图形类,我们给他一个求面积方法,但是每个形状求面积的方法都是不一样的,我们没有办法给出具体的方法体,所以我们需要让他的派生类(也就是子类)去重写这些抽象方法,去具体化的操作,也就是我们所说的多态,这样我们才能根据具体是实例去实现对应的方法。

那么在使用抽象类时我们需要注意什么呢??
1有抽象方法的类必须是抽象类,抽象类可以有抽象方法, 也可以有非抽象方法
2)抽象类不能new对象
3)一般来讲,抽象类的构造函数声明为protected,因为都是子类去实现,
4)当我们去用一般类去实现抽象类的时候,我们需要实现抽象类所有的抽象方法
5)抽象类无法被实例化,所以我们必须运用向上造型,才能调用抽象类(也就是父类)中的一般方法

那我们来实现一下抽象类

abstract class Shape{ //抽象类定义一个形状类,用abstract关键字修饰的类为抽象类

    private String type; //图形形状
    private String color; //图形颜色
    public Shape(){
        super();
    }  //调用的是object类的构造器

    protected Shape(String type, String color){ //构造方法 protected 让子类去调用
        this.type = type;
        this.color = color;
    }

    public abstract double calcuPerimeter(); //被abstract修饰的方法只能有方法名,方法名由子类实现。

    public abstract double calcuArea();

    public String getType(){ //可以有方法体的实现
        return this.type;
    }

    public String getColor(){
        return this.color;
    }

	//计算传入数组中所有的图形的面积
    public double fun(Shape[] shapes){
        double result = 0;
        for(Shape s: shapes){
            result += s.calcuArea();
        }
        return result;
    }

}

//我们在定义一个矩形去实现我们的抽象类,
class Retangle extends Shape{ //用普通类或者另一个抽象类去继承抽象类 但一定要实现方法体
    private double length;
    private double width;

    public Retangle(String color, String type, double length, double width){ //构造器
        super(type, color);	//调用父类有参构造器
        this.length = length;
        this.width = width;
    }

    @Override
    public double calcuPerimeter() {
        return 2 * (length + width);
    } //对父类的方法进行重写

    @Override
    public double calcuArea() {
        return length * width;
    }
}

//我们再定义一个圆形
class Circle extends Shape{
    private double radius;

    public Circle(String type, String color, double radius) {
        super(type, color);
        this.radius = radius;
    }

    @Override
    public double calcuPerimeter(){
        return 2 * Math.PI * radius;
    }

    @Override
    public double calcuArea() {
        return Math.PI * Math.pow(radius, 2);
    }
   // 我们来测试一下
 public static void main(String[] args) {
 //由于抽象类无法被实例化,所以我们需要用到向上转型,声明父类,但用子类去示例化
        Shape s = new Retangle("white", "rectangle", 18, 10);
        System.out.println(s.calcuArea());//计算一下当前矩形的面积
        
        //我们来计算一下所有的形状的面积,思路:先把他们存放在数组中,然后调用用fun方法
        
  		Shape[] sArr = new Shape[4];//可以存放Shape对象的数组,也就是说,虽然抽象类无法被示例化,但是却可以当作一个数据类型来使用
        sArr[0] = new Retangle("white", "rectangle", 18, 10);
        sArr[1] = new Circle("black", "circle", 3.5);
        sArr[2] = new Retangle("white", "rectangle", 18, 10);
        sArr[3] = new Circle("black", "circle", 3.5);
        
         System.out.println(s.fun(sArr));//s.fun(sArr)就是因为前面我们所说的无法示例化抽象类,如果要调用父类的方法,必须使用向上转型
}

结果:在这里插入图片描述

接口与抽象类有什么不同

表面上(直观上):
1.含有抽象方法(abstract修饰的方法)的类叫做抽象类,而用interface关键字+ interfacename(接口名)定义的是一个接口。
2.抽象类可以有构造函数,而接口没有构造函数(也就无法实例化接口,所以无法用 new 关键字)
3.抽象类的方法如果不写限定修饰符,那么就是默认访问权限,而接口如果不写限定修饰符,所有的方法及成员都是 public static fianl修饰
4.抽象类可以有普通的成员方法,而JDK1.8之后,接口可以有普通方法,但普通方法必须用default关键字修饰

使用上:
1.对于抽象类,我们必须先继承抽象类,再实现所有的抽象方法(不然再定义抽象类),而接口是常规类去实现(implements),并且实现接口中所有的方法。
2.抽象类的子类如果没有实现完抽象类种所有的方法,那么此类必须也定义为抽象类,存在多重继承,接口可以相互实现。

(自己理解)
抽象类可以理解为 “绝对有” ,而接口可以理解为 “可以有”
例如:门,门绝对有的功能是开门和关门。这两个方法我们就可以抽象化。
而密码门特有的功能是使用密码开门,而这个密码开门就可以理解为可以有。
那么就是门,绝对的方法:开门关门。密码门,不仅有开门关门,还有使用密码开门。那么密码门就可以去实现密码开门这个接口。而普通门不可以,因为如果实现了密码开锁,那么就不再是普通门,而是密码门。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值