初识Java(五)

目录

一、抽象类

1、介绍

2、为什么要有抽象类

3、规则

二、接口

1、介绍

2、为什么要有接口

3、接口的应用

三、内部类

1、实例内部类

2、静态内部类

3、局部内部类

4、匿名内部类


一、抽象类

1、介绍

抽象类只能被继承,使用abstract修饰,内部的成员方法没有具体实现,是抽象方法,抽象类被继承后,子类必须要重写父类的构造方法。

2、为什么要有抽象类

对代码多一层检验,提前发现错误。因为如果开发时本来不能使用父类,需要使用使用子类,但是不小心使用了父类,这就发生了错误,将父类设置为抽象类,由于抽象类不能直接使用,所以会提前提醒,尽早发现问题。

3、规则

基于上述抽象类的特性,所以会有以下几种规则:

  • 抽象方法不能被private,static,final修饰,因为会使得不能被重写,方法默认为public。
  • 抽象类中不规定必须要有抽象方法,但有抽象方法的类,一定是抽象类

二、接口

1、介绍

例:电脑的usb接口,只要一个产品符合相应的规范,就可以使用这个usb接口。

Java的接口与usb接口类似,只要一个类符合相应的规范,具有相关功能,就可以实现某个接口。

类之间的继承的关系是:is - a的关系,而接口之间是(xxxx具有xxxx)的功能。

例:猫是动物,具有跑的功能。

java 复制代码
public class Cat extends Animal implements IRunning {

}

语法格式:class换成了interface。

java 复制代码
public interface 接口名称 {

}

2、为什么要有接口

为了解决Java不能多继承的问题,一个类只能继承一个类,但是可以实现多个接口。

3、接口的应用

若有两个数据进行比较大小,如果是普通的数据类型可以直接比较,但是如果数据的类型是引用数据类型,那么不能直接进行比较,有两种方法,第一种方法 是使得数据的类实现Comparable接口,在类中重写接口的comparTo方法;第二种方法是不在类中写出比较的方法,直接创建新的类,这种类叫做比较器,让比较器实现Compartor接口,在比较器中重写接口中的compare方法。

第一种方法:

java 复制代码
class Student implements Comparable<Student> {
    private int age;
    private String name;

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

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}
public class Test01 {
    public static void main(String[] args) {
        Student student1 = new Student(10,"xxp");
        Student student2 = new Student(20,"zyt");
        System.out.println(student1.compareTo(student2));
    }
}

第二种方法:

java 复制代码
import java.util.Comparator;

class Student implements Comparable<Student> {
    public int age;
    public String name;

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

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}
class AgeCompartor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}
class NameCompartor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
public class Test01 {
    public static void main(String[] args) {
        Student student1 = new Student(10,"xxp");
        Student student2 = new Student(20,"zyt");
        //System.out.println(student1.compareTo(student2));
        AgeCompartor ageCompartor = new AgeCompartor();
        NameCompartor nameCompartor = new NameCompartor();
        ageCompartor.compare(student1,student2);
        nameCompartor.compare(student1,student2);
    }
}

这两种方法相比,第一种方法不如第二种灵活,因为第一种方法的只能比较一种,age或者name,不能兼得,第二种方法可以比较两种,灵活。


若给出一个数组,要将数组中的元素进行排序,而且里面的元素是引用数据类型,该如何比较呢?导入Arrays这个工具类,调用Arrays的sort方法,将数组作为参数传进去,由于传进去的是引用数据类型,所以sort方法会将数组的元素的类型强转为Comparable类,调用comparTo方法比较,所以数组的那些元素的类必须实现Comparable接口,否则无法强转。

java 复制代码
import java.util.Arrays;
import java.util.Comparator;

class Student implements Comparable<Student> {
    public int age;
    public String name;

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

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}

public class Test01 {
    public static void main(String[] args) {
        Student student1 = new Student(10,"xxp");
        Student student2 = new Student(20,"zyt");
        Student[] stu = {student1,student2,new Student(30,"lll")};
        Arrays.sort(stu);
    }
}

也可以将数组和比较器一起作为参数传进去,sort方法会根据比较器的比较原则,对数组中的元素进行比较。

java 复制代码
import java.util.Arrays;
import java.util.Comparator;

class Student implements Comparable<Student> {
    public int age;
    public String name;

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

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}
class AgeCompartor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}
class NameCompartor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
public class Test01 {
    public static void main(String[] args) {
        Student student1 = new Student(10,"xxp");
        Student student2 = new Student(20,"zyt");
        Student[] stu = {student1,student2,new Student(30,"lll")};
        AgeCompartor ageCompartor = new AgeCompartor();
        Arrays.sort(stu,ageCompartor);
    }
}
  • 4、浅拷贝与深拷贝

拷贝就是拷贝一个对象,产生新的对象。深浅之别在于,如果要拷贝的对象中,某个成员变量是引用,那么引用的对象如果不拷贝,就是浅拷贝,对象也拷贝的话,就是深拷贝。

浅拷贝:

java 复制代码
import java.util.Arrays;
import java.util.Comparator;

class Student implements Comparable<Student> ,Cloneable {
    public int age;
    public String name;

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

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test01 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student(10,"xxp");
        Student student2 = new Student(20,"zyt");
        Student student3 = (Student)student1.clone();
    }
}

深拷贝:

java 复制代码
import java.util.Arrays;
import java.util.Comparator;
class Money {
    public int m;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Student implements Comparable<Student> ,Cloneable {
    public int age;
    public Money money = new Money();
    public String string;

    public Student(int age, String string) {
        this.age = age;
        this.string = string;
    }

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //拷贝了普通数据
        Student student = (Student)super.clone();
        //拷贝对象
        student.money = (Money) this.money.clone();
        return student;
    }
}
public class Test01 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student(10,"xxp");
        Student student2 = new Student(20,"zyt");
        Student student3 = (Student)student1.clone();
    }
}
  • 5、抽象类与接口之间有什么区别

接口比抽象类更加抽象,接口里面不允许有普通的成员变量与普通的成员方法,抽象类不做要求。

接口里面的变量默认为public static final修饰,方法默认为public abstract。

三、内部类

当有需求,创建出一个对象只在一个类中使用时,那么可以将类创建在类里面,也就是内部类。

内部类分为4种:

1、实例内部类

由于内部类是类的成员,所以创建内部类对象时,要先创建出外部类的对象。

java 复制代码
public class Date {
    private int year;
    private int month;
    private int day;
    class Type {
        
    }
    
    public void setDate(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public static void main(String[] args) {
        Date date = new Date();
       
        Date.Type type = date.new Type(); //通过外部类创建的对象date去.new Type(),因为内部类是外部类的成员。
    }

注意:当内部类与外部类有同名的成员变量或者方法时,在内部类的方法中优先访问的是内部类中的变量和方法,如果非要访问外部类的,也可以,通过外部类名.this.可以完成访问。

2、静态内部类

java 复制代码
public class Date {
    private int year;
    private int month;
    private int day;
    static class Type {

    }

    public void setDate(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public static void main(String[] args) {
        Date date = new Date();

        Date.Type type = new Date.Type(); //因为是静态的,所以通过外部类名.内部类名
    }
}

3、局部内部类

这个用的很少,只能在方法体中使用。

4、匿名内部类

这个内部类没有名字。

java 复制代码
IA ia = new Ia () {
    
}
//这是一个匿名内部类的对象,然后将对象赋值给了ia
相关推荐
起名字真南2 分钟前
【OJ题解】C++实现字符串大数相乘:无BigInteger库的字符串乘积解决方案
开发语言·c++·leetcode
爬山算法8 分钟前
Maven(28)如何使用Maven进行依赖解析?
java·maven
tyler_download14 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
小小小~14 分钟前
qt5将程序打包并使用
开发语言·qt
hlsd#15 分钟前
go mod 依赖管理
开发语言·后端·golang
小春学渗透16 分钟前
Day107:代码审计-PHP模型开发篇&MVC层&RCE执行&文件对比法&1day分析&0day验证
开发语言·安全·web安全·php·mvc
杜杜的man19 分钟前
【go从零单排】迭代器(Iterators)
开发语言·算法·golang
亦世凡华、19 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
2401_8574396932 分钟前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧66633 分钟前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节