java-3 抽象类和接口

抽象类
 

//抽象类
abstract class Dog{
        public abstract void func();
//抽象方法必须搭配抽象类
}

1.抽象类不能够实例化,可以定义简单的成员变量,成员方法等等,唯一和普通类不一样的加上不能实例化。

2.抽象类虽然不能被实例化,但是可以被继承。抽象类就是为了被继承才存在的。

3.当一个普通类继承了抽象类时,如果这个抽象类包含抽象方法,则需要重写抽象方法,否则报错。

4.如果是一个抽象类继承了另一个抽象类,可以写也可以不重写抽象类的抽象方法。

5.抽象方法不能是private和static以及final。

接口

1.使用interface来表明是一个接口

2.接口当中的成员变量默认都是public static final修饰的。

3.接口当中的成员方法默认都是抽象方法,public abstract修饰的。

interface Tail{
    public int a =10;
    public final int b =5;
    public static final int c =1;
    void body();
    default void body1(){
        
    };
    public abstract void shake();
}
public class test {

}

4.接口当中的普通方法是不能有具体实现的,如果想让他有具体实现,需要在方法前加default,这个特性从JDK8才开始有的。加了default后,调用接口就会默认调用方法了。

5.接口中可以有静态的成员方法,但是不管是静态的还是default的方法,都是由public修饰的。

6.接口不能进行实例化。

7.一个抽象类实现一个接口,可以不重写这个抽象方法,但是当这个抽象类再次被继承,还是要重写。

8.用implements来关联类,然后重写抽象方法,否则报错。

如下:

interface Tail{
    public int a =10;
    public final int b =5;
    public static final int c =1;
    void body();
    default void body1(){

    };
    public abstract void shake();
}
class Cat implements Tail{
    public void body(){
        System.out.println("摇尾巴");
    }
    public void body1(){
        
    }
    public void shake(){
        
    }

}

其实我们可以直接创建一个接口:

 

然后选择interface 。

接口命名时,一般以大写字母I开头,接口中的方法和属性不要加仍和的修饰符号(public,private)的修饰符号,以保持代码的简洁性。

接口中不能有静态代码块和实例代码块以及构造方法。

接口的继承

interface Itail{
    void func();
}
interface Imouse{
    void funcB();
}
interface Ihand extends Imouse,Itail{
    void funcC();
}
class T implements Ihand{
    @Override
    public void func() {
        
    }

    @Override
    public void funcB() {

    }

    @Override
    public void funcC() {

    }
}

被继承的接口被类引用后,需要重写全部的接口的方法。

几个重要的接口

compareTo接口

public class L521 {
    public static void main(String[] args) {
        Student student1 = new Student("李",11,66.6);
        Student student2 = new Student("王",11,88.8);
        //如何比较这两个对象的大小?
        if(student1.compareTo(student2)>0){
            System.out.println("student1>student2");
        }
        if(student1.compareTo(student2)<0){
            System.out.println("student1<student2");
        }
        else {
            System.out.println("student1=studnet2");
        }
    }
}
class Student implements Comparable<Student>{
    public String name;
    public int age;
    public double score;

    //然后重写compare to方法


    @Override
    public int compareTo(Student o) {
    //o就是调用的参数,谁调用compareTo谁就是this
        if(this.age>o.age){
            return 1;
        }
        else if(this.age==o.age){
            return 0;
        }
        else {
            return -1;
        }
    }

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

当我们要对数据进行排序时也是同理,需要先重写compareTo去告诉用什么来排序

        //main里面
        Student student[] =new Student[3];
        student[0]=new Student("红",1,4);
        student[1]=new Student("绿",2,5);
        student[2]=new Student("蓝",3,6);
        System.out.println("排序前"+ Arrays.toString(student));
        Arrays.sort(student);
        System.out.println("排序后"+ Arrays.toString(student));
        
        //Arrays.sort(student,agecompare);
        //arrays还可以传递第二个参数,来指导用什么比较。

 comparator接口(比较器)

class Agecompare implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}

cloneable接口(克隆)

首先实现一个cloneable接口

class Person implements Cloneable{
    public int age = 0;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
        //调用object类来进行克隆
    }
}
public class L521 {
    public static void main(String[] args) throws CloneNotSupportedException {
    //通过alt+enter来抛出异常。
        Person person = new Person();
    //将clone的返回类型设置成peeson类型
        Person person2=(Person) person.clone();
    }
}

以上就完成了对象的克隆。产生了对象的副本。

深拷贝问题

class Person implements Cloneable{
    public int age = 0;
    public Money m = new Money();
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
        //调用object类来进行克隆
    }
}
class Money{
    public double money = 9.9;
}
public class L521 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person2=(Person) person.clone();
        person2.m.money=99.9;
        System.out.println(person.m.money);
        System.out.println(person2.m.money);
    }
}

是浅拷贝,因为只拷贝了这个对象,而没有拷贝这个对象引用所指向的对象。所以最后原本和副本都改变了。

深拷贝则需要:

class Money implements Cloneable{
    public double money = 9.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

在money类里实现cloneable接口后并重写方法

class Person implements Cloneable{
    public int age = 0;
    public Money m = new Money();
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.m=(Money) this.m.clone();
        return tmp;
        //调用object类来进行克隆
    }
}
class Money implements Cloneable{
    public double money = 9.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

在person里面使用tmp来储存一份拷贝,以此达到深拷贝。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值