​接口和抽象类

抽象类

abstrac关键字修饰的类

有抽象方法的类,必须是抽象类(方法和类都得加abstract关键字);

抽象类里可以没有抽象方法。

注意:1,抽象类和其他类的区别就是他不可以实例化对象(他就是用来被继承的),但可以有自己的成员变量,构造方法,成员方法。

2,可以有构造方法(当子类创建对象给其赋值)

3,抽象类的子类:要么是继续做抽象类,要么重写抽象类里的所有抽象方法

抽象方法

abstract修饰,  将子类共性的方法 (行为)抽取到 父类,由于每个子类执行的方法内容不一样, 父类不能确定方法体,就可以将其定义为抽象方法. 子类需要时再 进行重写,这样做可以统一规范子类方法的名字,形参,返回值类型等问题。

抽象方法不能被private,final,static修饰,因为修饰了子类就不能重写.

作用

因为方法重写只能是方法体不一样,  强制子类按照这个抽象方法格式重写,对同一行为方法统一名字,方便项目开发---其他开发人员对整个项目的理解和维护更加容易。

虽然用普通类也可以实现这个目的,但用抽象类,不规范的地方编译器会报错。比如创建了父类示例 ,重写改变了形参的格式

public abstract class Animal{
//抽象方法不需要写方法体,他定义为抽象方法就是为了让其他类重写
public abstract void eat(){}

}
//子类 Dog.java
public class Dog extends Animal{
@override
public  void eat(){
//不重写就会报错,提醒子类重写方法体
System.out.println(name + "不吃饭");
}
}
// 子类 Cat.Java
public class Cat extends Animal{
@override
public  void eat(){
System.out.println(name + "喜欢吃面");
}
}

接口

什么是接口?

        接口定义了一种规则,行为规范,一种引用数据类型。想让哪个类拥有这类行为就让这个类去实现相应的接口。

        接口多态:当一个方法的参数是接口时,可以传递接口的所有实现类对象.

格式

跟定义类的格式相同,将class关键字换成interface就实现了接口的定义

public    interface    接口名{};

接口中成员的特点 

属性:只能初始化常量,默认修饰符public static final 

构造方法:没有( 接口不能被实例化 )

方法:只能是抽象方法,默认修饰符public abstract

注:jdk7以前只能定义抽象方法

jdk8可以定义默认方法,静态方法

jdk9可以定义私有方法

在接口中,只有static ,default,private修饰的方法可以有方法体,因为不能被重写。 

默认方法

格式: default  返回值格式 方法名(参数列表){

}

用default修饰,不能省略,省略了就是默认修饰符;

提供默认实现,实现类可选择覆盖;

主要用于接口演化(向后兼容);

要实现多个接口中的默认方法,若存在多个默认方法的名字相同,则子类必须对该默认方法进行重写(因为名字相同对象就会不知道到底该调用哪一个方法)

静态方法

格式:public  static 返回值格式  方法名(参数列表){

}

方法static不能省略,直接用接口名调用

私有方法

方法中重复的代码抽取出来定义的方法 ,减小代码冗余

这是为内部方法服务的外界调用没有意义,所以用private修饰

为默认方法服务

格式:private  void  名(){}

为静态方法服务

格式:private  static void 名(){}

接口和类之间的关系

类与类: 只能单继承(extends), 不能多继承,但是可以多层继承.

类与接口:可以单实现(implements),也可以多实现.可以在继承一个类的同时实现多个接口

接口与接口:可以单继承(extends),也可以多继承.继承的子类必须重写全部父类的抽象方法

     extends扩展的意思,实现继承的作用,接口继承接口,相当于是把所有的抽象方法结合在一起。

     实现接口可以解决类不能多继承的局限性,就是让很多类用同一个规范实现自己的特性。

interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
接口的使用

一个类实现多个接口时,所有接口的抽象方法都要重写,如果不能则应设置为抽象类,因为抽象类里面可以存在其他非抽象方法。

提示:IDEA 中使用 ctrl + i 快速实现接口
定义三个接口
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}

子类继承父类并实现三个接口(想让duck实现哪种行为就实现相应接口,并重写里面的所有方法)

class Duck extends Animal implements IRunning, ISwimming, IFlying {
public Duck(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在用翅膀飞");
}
@Override
public void run() {
System.out.println(this.name + "正在用两条腿跑");
}
@Override
public void swim() {
System.out.println(this.name + "正在漂在水上");
}
}
空接口

一些接口里面没有抽象方法,名字又一般是形容词后缀-able的空接口,他的作用是标识,又称为标识接口。

public interface   Cloneable{}; 继承这个接口的类表示可以被克隆,拷贝。

克隆,拷贝是什么?

将原来对象里的内容复制一份,放在另一个独立的内存空间,他们的地址不一样。

什么是浅拷贝?

 拷贝的当前对象里还有其他类型的对象没有被拷贝。

深拷贝

克隆出完全独立于原来对象的对象。

实现排序的接口
public interface  comparable{} ;

Arrays.sort(),Collections.sort()这两个方法内部都实现了comparable接口,来实现对数组,集合的升序排序。

排序需要类实现comparable接口,重写内部的方法。但接口里只有comparTo(T),根据一个属性进行升序或者降序排序,不能适用复杂多变的情况。

public class User implements  Comparable<User>{ //实现接口后,指定泛型具体的类型

    private int  id;
    private  String name ;

    @Override
    public int compareTo(User o) {
        return this.id-o.id;//根据id升序,o.id-this.id就是降序
//根据id升序排列, 就不能用其他的方法排列,有很大局限性
    }
}

public interface comparator{};

如果要实现根据多个属性排序,自定义排序规则,就需要实现comparator接口,自定义比较器。

比较器有很多方法,可以满足很多需求。

Comparator有@FunctionalInterface,表明是函数式接口,可以用lambda表示式表示;

        ArrayList<User> num=new ArrayList<>();
        //匿名内部类形式
        Collections.sort(num, new Comparator<User>() {//匿名内部类实现了Comparator接口,重写compare方法
            @Override
            public int compare(User o1, User o2) {
                return o1.getId()-o2.getId();//根据User的id进行排序,
            }
        });
        //lambda表达式形式
        Collections.sort(num,((o1, o2) -> o1.getName().compareTo(o2.getName())));//字符串根据字典序排序

比较

特性ComparableComparator
包位置java.langjava.util
接口定义int compareTo(T o)int compare(T o1, T o2)
排序逻辑位置类的内部类的外部(定制排序)
使用场景类有默认排序规则时需要多种排序方式时
修改要求需要修改类本身(在类上实现comparable接口)无需修改原类(自定义比较器,参数类型为要比较的对象)
接口特性

1.因为接口是引用数据类型,所以不能new对象,接口中不能有静态代码块和构造方法;

2.接口的方法默认是public修饰,不用加其他权限修饰符(要能被其他类实现),重写接口方法也只能是public(重写的方法访问权限不能小于父类);

3.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class。

抽象类和接口的区别

1.虽然都不能实例化,但抽象类可以有构造方法,非抽象方法和成员变量,接口只能有成员常量和抽象方法 ;

2.抽象类之间只能单继承,接口之间可以多继承;

3.定义的关键字不一样,类class,接口interface;

实现他们的关键字也不一样,类extends,接口implements。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值