【Java】抽象类接口Object类

news2024/12/29 10:41:37

目录

1.抽象类

2.接口

2.1实现多个接口

2.2接口之间的关系

2.3接口使用实例

2.3.1Comparable接口

2.3.2Comparator接口

2.3.2Clone接口

2.4抽象类与接口的区别

3.Object类

3.1getClass方法 

3.2equals方法

3.3hashcode方法


1.抽象类

定义:抽象方法:这个方法没有具体的实现;

           抽象类:不能完全代表一个具体的对象。

注意

1> 使用 abstract 修饰;

2> 抽象类不能进行实例化,但普通类可以;

3> 抽象类中不一定包含抽象方法,但包含抽象方法的类一定是抽象类;

4> 抽象类中可以定义普通的成员变量和成员方法;

5> 抽象类存在的最大意义就是为了被继承,且多了一层编译器的校验;

6> 普通类继承抽象类后要重写抽象类中的抽象方法;

7> 抽象类A继承抽象类B后不需要重写,但当普通类C再继承抽象类A后,要重写所有没被重写的抽象方法;

8> 要满足重写的要求(如static和private不能被重写);

9> final关键字不可能和abstract同时作用在一个类或方法上;

10> 抽象类当中可以存在构造方法,在子类实例化时,会帮助父类的成员进行初始化。

abstract class Shape { //抽象类
    public int a;//普通成员变量
    public void print() { //普通成员方法
        System.out.println("Shape");
    }
    public abstract void draw(); //抽象方法
}
class Cycle extends Shape { //普通类
    @Override //普通类继承抽象类后要重写抽象类中的抽象方法
    public void draw() {
        System.out.println("○");
    }
}
abstract class Flower extends Shape {
    //抽象类继承抽象类,可以不重写父类的抽象方法
    abstract public void printf();//抽象方法
}
class Square extends Flower {
    @Override //见注意事项6
    public void draw() {
        System.out.println("□");
    }
    @Override
    public void printf() {
        System.out.println("❀");
    }
}

2.接口

定义:对公共行为的规范标准,是一种引用数据类型。相当于抽象类的进一步抽象。

注意

1> 使用 interface 定义;

2> 接口中不能有实现的方法,但是静态方法和被default修饰的方法可以实现;

3> 接口中的成员方法默认是public abstract修饰的;

4> 接口中的成员变量默认是public static final 修饰的;

5> 不能通过关键字new来实例化;

6> 类和接口之间使用implement进行关联;

7> 类实现接口后要重写接口中的抽象方法

8> 接口中存在default方法时可重写可不重写,具体看业务需求;

9> 不论是接口还是抽象类,都有向上转型

10> 子类实现接口方法时,这个方法一定要public修饰;

11> 接口中没有构造方法和代码块

12> 当一个类不想实现接口当中的方法时,这个类可以被定义为抽象类;

13> 接口的修饰符可以为abstract、public,不能为protected、private、final

interface IShape { //接口
    //成员方法默认为public abstract修饰,顾下列方法均为抽象方法
    public abstract void draw1();//抽象方法不可实现,public abstract可省略
    public void draw2();//抽象方法不可实现,public可省略
    public static void draw3() { //静态方法可以实现
        System.out.println("draw3");
    }
    default public void draw4() { //被default修饰的方法可以实现
        System.out.println("draw4");
    }
}
class Cycle implements IShape { //Cycle类实现了IShape接口
    @Override //重写接口中的抽象方法
    public void draw1() {
        System.out.println("○");
    }
    @Override //重写接口中的抽象方法
    public void draw2() {
        System.out.println("□");
    }
}
class Rect implements IShape { //同上
    @Override
    public void draw1() {
        System.out.println("□");
    }
    @Override
    public void draw2() {
        System.out.println("○");
    }
}
public class Test {
    public static void drawMap(IShape shape) { //多态
        shape.draw1();
    }

    public static void main(String[] args) {
        //IShape iShape = new IShape();//接口无法实例化自己
        IShape iShape1 = new Cycle();
        IShape iShape2 = new Rect();//向上转型

        drawMap(new Cycle());
        drawMap(new Rect());
    }
}

2.1实现多个接口

意义:一个类实现多个接口,可以解决Java中多继承的问题

注意:先继承类,再实现接口。

interface IFlying { //接口1
    void fly();
}
interface ISwimming { //接口2
    void swim();
}
interface IRunning { //接口3
    void run();
}
abstract class Animal { //抽象父类
    public String name;
    public int age;
    public Animal(String name, int age) { //带两个参数的构造方法
        this.name = name;
        this.age = age;
    }
    public abstract void eat(); //抽象方法
}
class Dog extends Animal implements IRunning,ISwimming{ //子类1
    public Dog(String name, int age) { //子类的构造方法
        super(name, age);
    }
    @Override //重写父类和接口的抽象方法
    public void swim() {
        System.out.println(this.name+"正在狗刨");
    }
    @Override
    public void run() {
        System.out.println(this.name+"正在跑");
    }
    @Override
    public void eat() {
        System.out.println(this.name+"正在吃狗粮");
    }
}
class Bird extends Animal implements IFlying { //子类2
    public Bird(String name, int age) { //子类的构造方法
        super(name, age);
    }
    @Override //重写父类和接口的抽象方法
    public void fly() {
        System.out.println(this.name+"正在飞");
    }
    @Override
    public void eat() {
        System.out.println(this.name+"正在吃虫子");
    }
}
public class Test {
    public static void testEat(Animal animal) { //多态
        animal.eat();
    }
    public static void testFly(IFlying iFlying) { //多态
        iFlying.fly();
    }
    public static void testRun(IRunning running) { //多态
        running.run();
    }
    public static void testSwim(ISwimming iSwimming) { //多态
        iSwimming.swim();
    }
    public static void main(String[] args) {
        testEat(new Bird("小鸟",3));
        testEat(new Dog("小狗",3));
        testFly(new Bird("小小鸟",2));
        testRun(new Dog("小小狗",2));
        testSwim(new Dog("小小小狗",1));
    }
}

2.2接口之间的关系

接口与接口之间关联用 extends,意为拓展,非继承。相当于把接口合并在一起。

interface A {
    void testA();
}
interface B {
    void testB();
}
interface C extends A,B { //此时C接口不仅有自己的功能,还有A接口和B接口的功能
    void testC();
}
class D implements C { //ABC中的抽象方法都要重写
    @Override
    public void testA() {
    }
    @Override
    public void testB() {
    }
    @Override
    public void testC() {
    }
}

2.3接口使用实例

2.3.1Comparable接口

//只根据年龄或成绩比较:

import java.util.Arrays;
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 //重写Comparable接口中的抽象方法
    public int compareTo(Student o) { //按年龄排序
        /*if (this.age - o.age > 0) {
            return 1;
        } else if (this.age - o.age == 0) {
            return 0;
        }else {
            return -1;
        }*/
        return this.age - o.age;
    }
}
public class Test {
    //模拟实现冒泡排序
    public static void bubbleSort(Comparable[] comparables) { //传入Comparable类型(实现了可比较接口)的数组
        for (int i = 0; i < comparables.length-1; i++) {
            for (int j = 0; j < comparables.length-1-i; j++) {
                //if (comparables[j]>comparables[j+1]) //无法直接比较
                if(comparables[j].compareTo(comparables[j+1]) > 0) { //使用重写的compareTo方法比较
                    Comparable tmp = comparables[j];
                    comparables[j] = comparables[j+1];
                    comparables[j+1] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {
        Student[] array = new Student[2];
        array[0] = new Student("zhangsan",20,88.8);
        array[1] = new Student("lisi",18,90);
        bubbleSort(array); //冒泡排序
        System.out.println("排序后:"+Arrays.toString(array));
    }
    public static void main2(String[] args) {
        Student student1 = new Student("xiaoming",14,98.5);
        Student student2 = new Student("xiaohong",16,59.9);
        int ret = student1.compareTo(student2);
        System.out.println(ret); //-1
    }
    public static void main1(String[] args) {
        Student[] array = new Student[3];
        array[0] = new Student("zhangsan",20,88.8);
        array[1] = new Student("lisi",18,90);
        array[2] = new Student("wangwu",21,68.9);
        System.out.println("排序前:"+ Arrays.toString(array));
        Arrays.sort(array); //Java自带的方法
        System.out.println("排序后:"+ Arrays.toString(array));
    }
}

2.3.2Comparator接口

//年龄成绩均可比较: 更加灵活

import java.util.Comparator;
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;
    }
}
class AgeComparator implements Comparator<Student> { //比较年龄
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}
class ScoreComparator implements Comparator<Student> { //比较成绩
    @Override
    public int compare(Student o1, Student o2) {
        return (int)(o1.score - o2.score);//score为double类型,需要强转为int类型
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student("xiaoming",14,98.5);
        Student student2 = new Student("xiaohong",16,59.9);

        AgeComparator ageComparator = new AgeComparator();
        int ret = ageComparator.compare(student1,student2);
        System.out.println(ret);//-2

        ScoreComparator scoreComparator = new ScoreComparator();
        int ret2 = scoreComparator.compare(student1,student2);
        System.out.println(ret2);//38
    }
}

2.3.2Clone接口

class Student implements Cloneable { //实现Cloneable接口
    public int age;
    public Student(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
    @Override
    protected Object clone() throws CloneNotSupportedException { //异常
        return super.clone();//子类重写的Object只是调用了父类的clone方法
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student(18);
        Student student2 = (Student) student1.clone();//向下转型,clone类型为Object,需强转为Student
        System.out.println(student1);//Student{age=18}
        System.out.println(student2);//Student{age=18} 克隆成功
    }
}

Ctrl+点击进入Cloneable接口后发现,该接口内什么东西都没有,why??

:这个接口被叫做标记接口,实现该接口证明当前的类是可以被克隆的。

//浅拷贝 

class Money {
    public double money;
}
class Student implements Cloneable { 实现Cloneable接口
    public int age;
    public Money m = new Money();
    public Student(int age) {
        this.age = age;
    }
    @Override //重写接口中的抽象方法
    protected Object clone() throws CloneNotSupportedException { 
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student(18);
        student1.m.money = 9.15;
        Student student2 = (Student) student1.clone();//克隆student1

        System.out.println(student1.m.money);//9.15
        System.out.println(student2.m.money);//9.15

        student1.m.money = 10;//更改student1
        System.out.println(student1.m.money);//10 按理说只有student1变
        System.out.println(student2.m.money);//10 但是实际上两个都变了
                                             //这就是浅拷贝,没有克隆当前对象内更深层的变量
    }
}

//深拷贝

class Money implements Cloneable { //实现Cloneable接口
    public double money;
    @Override //重写接口中的抽象方法
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Student implements Cloneable { //实现Cloneable接口
    public int age;
    public Money m = new Money();
    public Student(int age) {
        this.age = age;
    }
    @Override //重写接口中的抽象方法
    protected Object clone() throws CloneNotSupportedException {
       Student tmp = (Student) super.clone();//先克隆当前对象
       tmp.m = (Money) this.m.clone();//再克隆当前对象里更深层的变量
       return tmp;
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student(18);
        student1.m.money = 9.15;
        Student student2 = (Student) student1.clone();//克隆student1

        System.out.println(student1.m.money);//9.15
        System.out.println(student2.m.money);//9.15

        student1.m.money = 10;//更改student1
        System.out.println(student1.m.money);//10    深拷贝,只修改了student1
        System.out.println(student2.m.money);//9.15  不影响student2内的值
    }
}

2.4抽象类与接口的区别

区别

抽象类(abstract)接口(interface)
结构组成普通成员变量+抽象方法抽象方法+全局变量
权限各种权限public
子类使用使用extends继承抽象类使用implement实现接口
关系一个抽象类可以实现若干接口借口不能继承抽象类,但可使用extends拓展多个父接口
子类限制一个子类只能继承一个抽象类一个子类可以实现多个接口

3.Object类

定义:Object是Java默认提供的一个类,是参数的最高同一类型。除了Object类,所有的类都是存在继承关系的。默认所有类继承Object父类

疑问:之前我们学过,一个类只能继承一个类,这里的意思是只能同时继承一个类。

例如:Dog类继承Animal类,而Animal类又默认继承Object类,所以Dog类间接继承了Object类,没有违背一个类只能继承一个类这一说明。

//使用Object类接收所有类的对象

class Student {
    public int age;
    public Student(int age) {
        this.age = age;
    }
}
public class Test {
    public static void main(String[] args) {
        Object object1 = new Student(1);//Object可接收所有类的对象
    }
}

 

3.1getClass方法 

public class Test {
    public static void main(String[] args) {
        Student student = new Student(10);
        Class<?> c = student.getClass();//Class<?> 这里涉及到了泛型,在之后的数据结构中会讲解
        System.out.println(c);//class Demo2.Student —— 在Demo2包下的Student类中
    }
}

3.2equals方法

进入Object的equals方法后,我们发现代码仍是使用地址比较,所以若想比较数据大小,必须要重写equals方法:

import java.util.Objects;
class Student {
    public int age;
    public Student(int age) {
        this.age = age;
    }
    @Override //根据自身需求重写equals方法
    public boolean equals(Object obj) {
        Student student = (Student) obj;
        return age == student.age;
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student(10);
        Student student2 = new Student(10);
        System.out.println(student1==student2);//比较地址,false
        //System.out.println(student1.equals(student2));//父类Object中的equals仍是比较地址,false
        System.out.println(student1.equals(student2));//重写equals后比较年龄大小,true
    }
}

3.3hashcode方法

定义:此方法帮我们算了一个具体的对象位置,用来确定对象在内存中存储的位置是否相同。一般在散列表中才有用,其他情况下无用。

import java.util.Objects;

class Student {
    public int age;
    public Student(int age) {
        this.age = age;
    }
    @Override //使用Generate生成
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age;
    }
    @Override //使用Generate生成
    public int hashCode() {
        return Objects.hash(age);
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student(10);
        Student student2 = new Student(10);//没重写hashCode:不一样
        //System.out.println(student1.hashCode());//460141958
        //System.out.println(student2.hashCode());//1163157884
                                                //重写hashCode后:一样
        System.out.println(student1.hashCode());//41
        System.out.println(student2.hashCode());//41

    }
}

第一篇万字博客,爽 dei dei ~~~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/483159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Cursor Tool] 面向编程的ChatGPT工具的入门使用指南

文章目录 0. 面向编程的ChatGPT工具的入门使用指南1. Cursor的下载和安装2. Cursor的基本功能的使用2.1 关于Cursor的Chat模式2.2 关于Cursor的Edit模式 3 关于Cursor的项目级应用4 使用Cursor帮助我们从项目的设计出发来为我们提供建议 0. 面向编程的ChatGPT工具的入门使用指南…

车载软件架构——闲聊几句AUTOSAR BSW(三)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 我特别喜欢一个老话,来都来了。我觉得这就是松弛感,既然来了,就开心起来吧!松弛感来自于专注,焦虑不是靠克服的,是靠忘记的,当你很专注做一件事的时候…

剪枝与重参:课程总结

目录 课程总结前言1. 基础快速入门2. 基于VGG的模型剪枝3. 英伟达2-4剪枝方案4. YOLOv8剪枝5. ACNet、DBB、RepVGG重参个人总结 课程总结 前言 手写AI推出的全新模型剪枝与重参课程。记录下个人学习笔记&#xff0c;仅供自己参考。 本次课程主要是课程总结&#xff0c;对之前学…

设计模式之代理模式(静态代理动态代理)

目录 1、什么是代理模式 2、代理模式的结构 3、代理模式的实现 3.1 静态代理和动态代理概念 3.2 静态代理 3.3 动态搭理 3.3.1 代码实现 3.3.2 Proxy类讲解 4、动态代理VS静态代理 5、代理模式优缺点 1、什么是代理模式 由于某些原因需要给某对象提供一个代理以控制对…

【开发工具】 Adobe 2022 最详细的安装方法 就是这么简单 绿色 安全方便

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

vulnhub靶场之Black-Widow-final

1.信息收集 探测存活主机&#xff0c;发现192.168.239.177存活 对目标主机192.168.239.177进行端口扫描&#xff0c;发现存活22、80、111、2049、3128等端口 在浏览器中访问http://192.168.239.177&#xff0c;并查看源码&#xff0c;未发现有用的信息 对http://192.168.23…

【openGauss实战11】性能报告WDR深度解读

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

c++题库练习

19. 以下叙述中正确的是&#xff08;&#xff09; A 使用typedef说明新类型名时&#xff0c;其格式是&#xff1a; typedef 新类型名 原类型名; B 在程序中&#xff0c;允许用typedef来说明一种新的类型名 C 使用typedef 说明新类型名时&#xff0c;后面不能加分号 D 在使用typ…

three.js学习 06 - 结合GSAP(补间动画)设置各种动画效果(运动效果与双击暂停动画等效果)

1. GSAP简介 GSAP&#x1f44d;&#x1f3fc;是前端业内非常有名的一个动效库&#xff0c;有大量的优秀的网站都在使用它。它不仅能在原生JS的环境下使用&#xff0c;也能配合各种当前流行的框架进行使用。 通过使用它&#xff0c;非常多原本实现起来很有难度的交互动画效果&a…

计算机必读基础书籍

计算机必读数据 一&#xff1a;故事背景1.1 前言1.2 提示 二&#xff1a;计算机组成2.1 是什么2.2 有什么2.2.1 计算机系统概述2.2.2 数据信息的表示2.2.3 运算方法与运算器2.2.4 存储系统2.2.5 指令系统2.2.6 中央处理器2.2.7 指令流水线2.2.8 总线系统2.2.9 输入输出 2.3 思维…

[MAY DAY]五一综合训练 之——最值问题

文章目录 > **## * 要赋值 &#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; *** %#&#xffe5;#%#*&&#xff01;&#xff01;&#xff01;&#xff01;要赋值一、双指针求最大连续和双指针算法分析&#xff1a; 注意&#xff…

Java学习笔记-03

目录 类与对象 类class 对象 修饰符private this关键字 构造函数 继承 权限修饰符 包package 状态修饰符final 类与对象 类 类是对现实生活中一类事物的抽象&#xff0c;里面包含了这类事物共有的属性(名词)和行为(动词)例如人类&#xff0c;人就是一个大类&#xff…

大规模MIMO系统中基于CSI的卷积神经网络定位

来源&#xff1a;投稿 作者&#xff1a;小灰灰 编辑&#xff1a;学姐 论文标题&#xff1a;CSI-based Positioning in Massive MIMO systems using Convolutional Neural Networks 摘要 研究了使用大规模MIMO&#xff08;MaMIMO&#xff09;系统的信道状态信息&#xff08;CS…

mysql 基础操作命令集

目录 目录 数据库操作 查看库命令 使用某个库&#xff08;可以不用分号 &#xff1b;&#xff09; 查看库下所有的表 显示一个表下的所有字段和类型 查看一个表的建表语句 查看表的内容 创建新数据库 创建新表&#xff0c;设定表的字段 插入一行数据 某字段更改数据…

OSI七层模型及各层功能概述

1.OSI的基本概念及原则 OSI是Open System Interconnect的缩写&#xff0c;意为开放式系统互联。其各个层次的划分遵循下列原则&#xff1a; &#xff08;1&#xff09;同一层中的各网络节点都有相同的层次结构&#xff0c;具有同样的功能。&#xff08;2&#xff09;同一节点…

运营商大数据是什么,是如何实现精准获客的

近年来&#xff0c;运营商大数据在市场之上发展迅速&#xff0c;各行各业的公司都在利用运营商大数据获取更加精准有效的企业信息和客户资源。例如&#xff0c;当企业在进行精准营销的过程之中&#xff0c;可以根据线索和条件快速获得更准确的客户名单&#xff0c;而不像传统的…

定时任务方案实现与对比

定时任务分类 定时任务分为分布式定时任务和单机定时任务两个大的方向&#xff0c;他们的适用场景不同。 单机定时任务在单台计算机上运行&#xff0c;其执行结果和单台机器上的数据有关&#xff0c;如对本地机器的缓存做核对、清理日志等。它的 优点 是简单易用&#xff0c;无…

玩着3dmax把Python学了-01

3ds Max 2022以前的版本要借助Python的api来实现Python编程达到编辑绘图脚本的功能&#xff0c;但是好消息来了&#xff0c;3ds Max 2022 起&#xff0c;MaxPlus 不再作为 3ds Max 的 Python API 包含在内。而是3ds Max 将 Python 3.7 的标准版本包涵其中了&#xff0c;位于 [3…

MySQL监控告警及可视化:Zabbix+Percona PMP实现(Part II)

MySQL监控告警及可视化&#xff1a;ZabbixPercona PMP实现&#xff08;Part II&#xff09; PMP插件安装PMP监控脚本配置Web界面导入PMP模板 服务器清单如下&#xff1a; 服务器IP配置OS版本服务器角色172.16.175.x4c8gCentOS 7.7MySQL Server172.16.175.y4c8gCentOS 7.7Zabbi…

Python——基于YOLOV8的车牌识别(源码+教程)

目录 一、前言 二 、完成效果 三、 项目包 四、运行项目 &#xff08;教程&#xff09; 一、前言 YOLOv8LPRNet车牌定位与识别https://www.bilibili.com/video/BV1vk4y1E7MZ/ 最近做了有一个车牌识别的小需求&#xff0c;今天完成了&#xff0c;在此记录和分享 首先&#x…