IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【浅学Java】关于Java中的【抽象类】【接口】【深拷贝】,你真的会了吗? -> 正文阅读

[Java知识库]【浅学Java】关于Java中的【抽象类】【接口】【深拷贝】,你真的会了吗?

抽象类

1. 抽象类的概念

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类————即方法里面没有内容,只有一个空壳子

2.抽象类的知识点

1、被abstract修饰的类就是抽象类
2、被abstract修饰的方法就是抽象方法
3、抽象类不能被实例化,就不能被 new
4、抽象类里面的成员和普通类里面的成员一样,只不过不能被实例化
5、当一个普通的类继承这个抽象类之后,那么这个普通类,必须重写这个抽象类中的所有方法
6、抽象类存在的最大的意义就是被继承
7、抽象类也可以发生向上转型,进一步发生多态
8、当一个抽象类A 继承了 抽象类B 时,就像类A 就不用重写抽象类B中的方法
9、当一个普通类 继承了第8条的 A时,此时就得重写A 和 B中所有的抽象方法
10、final不能修饰抽象方法,也不能修饰抽象类,因为被final修饰的一定不能被继承,而被abstract修饰的必须得继承
11、抽象方法也不能被private修饰,原因:抽象方法必须被重写,但是被private修饰后,子类都无法访问父类中的该方法
12、抽象方法不能被static修饰,原因:static修饰的静态类要是被重写,在调用时,也不能动态绑定到子类的方法,没有任何的意义
13、抽象类当中不一定有抽象方法,但是有抽象方法的类一定时抽象类

看一个代码:

abstract class Shape{
    public abstract void draw();
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("?");
    }
}

class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("?");
    }
}

class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("🔺");
    }
}
public class TestDemo {
    public static void drawMap(Shape shape){
        shape.draw();
    }
    public static void main(String[] args) {
        Cycle cycle=new Cycle();
        Rect rect =new Rect();
        Triangle triangle=new Triangle();
        drawMap(cycle);
        drawMap(rect);
        drawMap(triangle);
    }
}

3. 抽象类的作用

抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.

普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?

确实如此. 但是使用抽象类相当于多了一重编译器的校验.
使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.

很多语法存在的意义都是为了 “预防出错”, 例如我们曾经用过的 final 也是类似. 创建的变量用户不去修改, 不
就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候, 让编译器及时提醒我们.
充分利用编译器的校验, 在实际开发中是非常有意义的

接口

1. 接口的概念

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型

2. 接口的知识点

1、接口使用关键字 interface 来修饰
2、接口当中的成员方法,只能是抽象方法。所有的方法 默认都是public abstract
3、接口当中的成员变量默认是public static final
4、接口当中的方法,如果要实现,需要用 default 来修饰
5、接口当中的静态方法可以有具体的实现
6、接口不能进行实例化,即不能 new
7、一个普通的类,可以通过 implements 来实现这个接口
8、接口中不能有静态代码块和构造方法
9、接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
10、如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
11、jdk8中:接口中还可以包含default方法。
12、一个类,可以继承抽象类,同时实现多个接口。每个接口之间使用逗号分割
13、接口和类之间的的关系是implements。接口和接口之间关系是extends,意为拓展。
14、当接口C 拓展了 A,B时,如果有类 D implements C,则在D中必须重写A,B,C 中所有的方法。

代码示例:

class Animal{
    public String name;
    public int age;
    public Animal(String name){
        this.name=name;
    }
    public void est(){
        System.out.println(this.name+"吃饭饭!");
    }
}
interface IFlying{
    void fly();
}
interface IRunning{
    void run();
}
interface ISwimming{
    void swim();
}

class Dog extends Animal implements IRunning,ISwimming{
    public Dog(String name){
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name+"正在跑!");
    }

    @Override
    public void swim() {
        System.out.println(this.name+"正在游泳!");
    }
}
class Cat extends Animal implements IRunning{
    public Cat(String name){
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name+"正在跑!");
    }
}
class Duck extends Animal implements ISwimming,IRunning,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+"正在游泳");
    }
}
public class TestDemo {
    public static void walk(IRunning iRunning){
        iRunning.run();
    }
    public static void fly(IFlying iFlying){
        iFlying.fly();
    }public static void swim(ISwimming iSwimming){
        iSwimming.swim();
    }
    public static void main(String[] args) {
        swim(new Dog("wang"));
        walk(new Cat("mimi"));
        swim(new Duck("唐老鸭"));
    }
}

3.三个比较重要的接口

3.1 comparable

在Java当中,如果引用类型比较大小,需要具备以下两个条件:
1.可以比较
2.重写了某个方法

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

    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 +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        if(this.age>o.age){
            return 1;
        }else if(this.age==o.age){
            return 0;
        }else{
            return -1;
        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0]=new Student("zhangsan",98,78.9);
        students[1]=new Student("lisi",18,18.9);
        students[2]=new Student("zns",68,88.9);
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

上面代码的不足之处在:对原始类的侵入性太强
下面,我们进行改进:

class Student{
    public String name;
    public int age;
    public double score;

    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 +
                '}';
    }
}
class AgeComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}

class StringComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1,Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
class ScoreComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1,Student o2) {
        return (int)(o1.score-o2.score);
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0]=new Student("zhangsan",98,78.9);
        students[1]=new Student("lisi",18,18.9);
        students[2]=new Student("wns",68,88.9);

        //按年龄大小排序
        AgeComparator ageComparator=new AgeComparator();
        Arrays.sort(students,ageComparator);
        System.out.println(Arrays.toString(students));

        //按照首字母排序
        StringComparator stringComparator =new StringComparator();
        Arrays.sort(students,stringComparator);
        System.out.println(Arrays.toString(students));

        //按照成绩排序
        ScoreComparator scoreComparator =new ScoreComparator();
        Arrays.sort(students,scoreComparator);
        System.out.println(Arrays.toString(students));
    }
}

3.2Cloneable 接口和深拷贝

发生克隆的条件:

  1. 可以克隆
  2. 重写object克隆方法
class Person implements Cloneable{
    public String id="1234";

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                '}';
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person();
        Person person2=(Person)person1.clone();
    }
}

代码分析:
在这里插入图片描述
图解代码功能:

在这里插入图片描述
上面的代码看似已经对拷贝进行了实现,但是如果一个类中有示例话的对象时,上述代码也就只能实现浅拷贝,就像下面的代码一样:

class Money{
    int money=30;
}
class Person implements Cloneable{
    public String id="1234";
    Money m=new Money();

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person();
        Person person2=(Person)person1.clone();

        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("==============");
        person1.m.money=90;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

运行结果:
在这里插入图片描述
图解代码:
在这里插入图片描述
上述代码只进行了浅拷贝,并没有对对象中的实例化对象进行拷贝,只能拷贝了它的地址,即person1.m.money和person2.m.money是同一个对象,下面我们将进行深拷贝:

class Money implements Cloneable{
    public int money=30;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public String id="1234";
    Money m=new Money();
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp=(Person)super.clone();
        tmp.m=(Money)this.m.clone();
        return tmp;
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person();
        Person person2=(Person)person1.clone();

        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("==============");
        person1.m.money=90;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

在这里插入图片描述
代码分析:
在这里插入图片描述
图解代码:
在这里插入图片描述
在上面的代码中,进行了深拷贝之后,即对 m 也进行了拷贝,所以修改person1.m.money时,person1.m.money并没有改变。

3.3 Object类

Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收

3.3.1 对象比较equals方法——判断对象的内容是否一致

在Java中,==进行比较时:

  1. 如果==左右两侧是基本类型变量,比较的是变量中值是否相同
  2. 如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同
  3. 如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的。
class Student{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;//两个引用引用同一个对象
        if (o == null || getClass() != o.getClass()) return false;
        //o在这里代表的就是student2,即当student2为空时。
        //getClass()的作用是获取类型,即当两个对象的类型不一样时
        Student student = (Student) o;//将o强制类型转换为Student类型
        return age == student.age && Objects.equals(name, student.name);//比较age和name属性
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student student1=new Student("lisi",19);
        Student student2=new Student("lisi",19);
        System.out.println(student1.equals(student2));
    }
}

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

代码分析:
在这里插入图片描述

3.3.2 hashcode方法——计算对象具体存在的位置

当两个对对象所指定的属性一致时,就认为她两位置一样,即hashcode的值一样

class Student{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student student1=new Student("lisi",19);
        Student student2=new Student("lisi",19);
        System.out.println(student1.hashCode());
        System.out.println(student2.hashCode());
    }
}

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

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:36:51  更:2022-04-14 23:42:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:20:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码