接口(续)和Object类

时间:2022-10-13 13:52:27

一.接口

1.实现多个接口

在Java中不支持多继承,但是一个类可以实现多个接口。就像鸭子,可以飞,跑,游,我们可以用三个接口实现;对于多个接口的实现,须用implements关键字,而接口之间,用逗号隔开。

例1:

interface IFlying{
    void Flying();
}
interface IRunning{
    void Running();
}
interface ISwimming{
    void swimming();
}
class Duck  implements IFlying,IRunning,ISwimming{
    public String name;
    public Duck (String name){
       this.name = name;
    }
    @Override
    public void Flying() {
        System.out.println(this.name+"天上飞");
    }
    @Override
    public void Running() {
        System.out.println(this.name+"地上跑");
    }
    @Override
    public void swimming() {
        System.out.println(this.name+"水里游");
    }
}
public class Test {
    public static void main(String[] args) {
      Duck d = new Duck("白糖");
      d.Flying();
      d.Running();
      d.swimming();
    }
}

执行结果:

白糖天上飞
白糖地上跑
白糖水里游

这就是一个类实现多个接口,它们接口中的抽象方法必须要全部实现

2.接口之间的继承

与类的继承不同的是,一个接口可以有一个以上的父接口,它们之间用逗号分隔,形成父接口列表。新接口将继承所有父接口中的常量、抽象方法和默认方法,但不能继承父接口中的静态方法,也不能被实现类所继承。

例2:

interface IRunning{
    void Running();
}
interface ISwimming{
    void swimming();
}
interface IAmphibian extends ISwimming,IRunning{

}
class Duck  implements IAmphibian{
    public String name;
    public Duck (String name){
       this.name = name;
    }

    @Override
    public void Running() {
        System.out.println(this.name+"地上跑");
    }

    @Override
    public void swimming() {
        System.out.println(this.name+"水里游");
    }
}

接口间的继承相当于把多个接口合并在一起.

3.接口中的静态方法和默认方法

①.静态方法

接口中的静态方法不能被子接口继承,也不能被实现该接口的类继承。对接口中静态方法的访问,可以通过接口名直接进行访问,即用“接口名.静态方法名()”的形式进行调用。

②.默认方法

接口中的默认方法用default修饰符来定义,默认方法可以被子接口或被实现该接口的类所继承,接口中的默认方法有方法体,须通过接口实现类的实例进行访问,即通过“对象名.默认方法名()”的形式进行访问。

例3:在接口中定义默认方法和抽象方法,和静态方法

interface Face{
    final static double  PI = 3.14;//定义常量
    //定义默认方法--计算面积
    public default double area(int r){
        return r*r*PI;
    }
    //定义抽象方法
    double volume(int r,double h);
    //定义静态方法
    public static String show(){
        return "我是静态方法";
    }
}
public class Test implements Face{
  //实现接口的方法
    @Override
    public double volume(int r, double h) {
        return area(r)*h;
    }

    public static void main(String[] args) {
        System.out.println(Face.show());
        Test t = new Test();
        System.out.println("圆柱的体积 = "+t.volume(1, 2.0));
    }
}

结果如下:

我是静态方法
圆柱的体积 = 6.28

4.接口的使用实例

对象数组排序

自定义的学生类要具备可以比较的功能,就需要接口来实现,介绍Comparable,Comparator两种比较机制

(1).Comparable 自然排序

Comparable 接口只包括一个函数,它的定义如下

public interface Comparable<T> {
    public int compareTo(T o);
}

Comparable具体的比较规则是按照 compareTo 方法中的规则进行。这种顺序称为 自然顺序。
compareTo 方法的返回值有三种情况:

  • s1.compareTo(s2) >0 即 s1 > s2;
  • s1.compareTo(s2) <0 即 s1 < s2;
  • s1.compareTo(s2) =0 即 s1 = s2;
    也可以重写compareTo的方法
    例4
class Sturdnt implements Comparable<Sturdnt>{
    public String name;
    public  int score;
    public Sturdnt(String name,int score){
        this.name = name;
        this.score = score;
    }
    @Override
    public int compareTo(Sturdnt o) {
        return this.score - o.score;
    }
}
public class Test {
    public static void main(String[] args) {
        Sturdnt s1 = new Sturdnt("大飞",89);
        Sturdnt s2 = new Sturdnt("白糖",90);
        if(s1.compareTo(s2) > 0){
            System.out.println("s1 > s2");
        } else if (s1.compareTo(s2) < 0) {
            System.out.println("s1 > s2");
        }else {
            System.out.println("s1 > s2");
        }
    }
}

(2).Comparator 定制排序

Comparator可以在类的外部使用,然后把该接口实现类的匿名对象当作参数传给排序方法中。可以拥有多个接口实现类,实现按照不同属性进行排序
如例5:

class Sturdnt {
    public String name;
    public  int score;
    public Sturdnt(String name,int score){
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Sturdnt{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }

}
class ScoreComparator implements Comparator<Sturdnt>{

    @Override
    public int compare(Sturdnt o1, Sturdnt o2) {
        return o1.score -o2.score;
    }
}
class NameComparator implements  Comparator<Sturdnt>{
    @Override
    public int compare(Sturdnt o1, Sturdnt o2) {
        return o1.name.compareTo(o2.name);
    }

}

public class Test1 {
    public static void main(String[] args) {
        Sturdnt[] sturdnts = new Sturdnt[3];
        sturdnts[0] = new Sturdnt("大飞",89);
        sturdnts[1] = new Sturdnt("白糖",90);
        sturdnts[2] = new Sturdnt("武松",99);
        ScoreComparator scoreComparator = new ScoreComparator();
        Arrays.sort(sturdnts,scoreComparator);
        System.out.println(Arrays.toString(sturdnts));
        NameComparator nameComparator = new NameComparator();
        Arrays.sort(sturdnts,nameComparator);
        System.out.println(Arrays.toString(sturdnts));
    }
}


输出结果:

[Sturdnt{name=‘大飞’, score=89}, Sturdnt{name=‘白糖’, score=90}, Sturdnt{name=‘武松’, score=99}]
[Sturdnt{name=‘大飞’, score=89}, Sturdnt{name=‘武松’, score=99}, Sturdnt{name=‘白糖’, score=90}]

二.Object

所有的类都是直接或间接地继承Object类而得到的。即如果某个类没有使用extends关键字,则该类默认为java.lang.Object类的子类。所以说Object类是所有类的源,也就是所有类的对象都可以使用Object的引用进行接收。
例:使用Object接收所有类的对象

class Student{}
public class Text {
    public static void func(Object obj){
        System.out.println(obj);
    }
    public static void main(String[] args) {
        func(new Student());
    }
}

执行结果:

Student@1b6d3586
介绍几个方法:

1.equals方法

在Java中,“==”运算符用于比较两个变量本身的值,即两个对象在内存中的首地址,而equals()方法则是比较两个字符串中所包含的内容是否相同;如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的
例1:

class Student{
        public int score;
        public String name;
        public Student(String name,int score){
            this.name = name;
            this.score = score;
        }
    public boolean equals(Object obj) {
        if (obj == null) {
            return false ;
        }
        if(this == obj) {
            return true ;
        }
        // 不是Person类对象
        if (!(obj instanceof Student)) {
            return false ;
        }
       Student student = (Student) obj ; // 向下转型,比较属性值
        return this.name.equals(student.name) && this.score==student.score ;
    }
}
public class Text {
    public static void main(String[] args) {
      Student s1 = new Student("白糖",100);
      Student s2 = new Student("白糖",100);
        System.out.println(s1.equals(s2));
    }
}

执行结果:true

注: 比较对象中内容是否相同的时候,一定要重写equals方法。

2.toString()方法

toString()方法的功能是将调用该方法的对象的内容转换成字符串,并返回其内容,但返回的是一些没有意义且看不懂的字符串,所以可以直接重写Object类中toString()方法

class Student{
        public int score;
        public String name;
        public Student(String name,int score){
            this.name = name;
            this.score = score;
        }
        public String toString() {
        return "Student{" +
                "score=" + score +
                ", name='" + name + '\'' +
                '}';
    }
}
public class Text {

    public static void main(String[] args) {
      Student s1 = new Student("白糖",100); 
      System.out.println(s1);
    }
}

执行结果:

Student{score=100, name=‘白糖’}