首页 > 编程语言 >JAVA接口详解

JAVA接口详解

时间:2024-03-26 12:32:42浏览次数:29  
标签:JAVA void System 接口 age 详解 Student println public

一,抽象类

抽象类为用abstract修饰的类

1,定义的成员变量与普通的类没有区别

2,抽象类不可以被实例化

3,当一个类不具体描述某个对象时,可以定义为抽象类

4,如果一个类包含抽象方法,则这个类必须是抽象类,没有抽象方法,也可以被称为抽象类

5,一个方法可以被修饰为abstract,这个方法可以不被实现,被称为抽象方法

例如:public abstract void draw();

6,抽象类也可以发生向上转型,动态绑定,多态 

7,抽象方法,满足重写特点,(一定要被子类重写)被static,final,private、修饰都是不能发生重写的

 @Override
    public void draw() {
        System.out.println("画一个矩形");
    }
}//对draw()方法的重写

8,当一个普通类A,继承了一个抽象方法,但不想重写抽象类的方法,可以把A改为一个抽象类,但如果A被B继承,则B这个类要重写所有的抽象方法

二,接口

1,接口用interface来定义

2,接口中的成员变量默认被public static final修饰,且接口中的成员变量必须要初始化。所以有以下两种写法:

法一:public static final int age1=10;
法二:int age1=10;

3,接口的方法,默认被public abstract修饰,故为抽象方法,不能有具体的实现,一般直接写为void draw();

4,接口为引用类型,所以不能被实例化为对象

5,接口中定义的方法能具体的实现的有两种:第一种为default修饰的方法,第二种为静态方法

void text1();  
 public static void text2 (){
        System.out.println("静态方法");
    }
    public default void text3(){
        System.out.println("default方法");
    }//接口中的方法
@Override
public void text1() {
    System.out.println("重写text1");
}

@Override
public void text3() {
    System.out.println("重写default");//在实现接口的类中,对接口方法进行重写

我们可以通过实例化,用对象的引用来访问重写的text1和text3,也可以用接口名访问访问接口中的静态方法<A.text2();>。default修饰的方法并不是必须要重写的。

6,使用接口时,用关键字implements来实现。例如:class A implements IB{}

7,当一个类实现了这个接口,就要对接口中的方法进行重写(因为接口中的方法为抽象方法)

8,一个类可以实现多个接口,但这个类一定要重写以上接口中的全部抽象方法。例如:

interface IA{
    void textA();

}
interface IB{
    void textB();
}
class Demo2 implements IA ,IB{

    @Override
    public void textA() {
        System.out.println("textA");
    }

    @Override
    public void textB() {
        System.out.println("textB");
    }
}

9,接口可以继承多个接口,用关键字extends来实现。例如:interface IA{};interfaceI B{};interface IC extends IA,IB{};而实现接口IC的这个类中,一定要重写IA,IB,IC中的所有抽象方法。

接口的初步练习:

public interface IUSB {
    void openDevice();
    void closeDevice();
}--------------------------
public class KeyBoard implements IUSB{

    @Override
    public void openDevice() {
        System.out.println("打开键盘");
    }

    @Override
    public void closeDevice() {
        System.out.println("关闭键盘");

    }
    public void input(){
        System.out.println("键盘输入");
    }
}----------------------------------------
public class Mouse implements IUSB{

    @Override
    public void openDevice() {
        System.out.println("打开鼠标");
    }

    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标");

    }
    public void click(){
        System.out.println("点击鼠标");
    }

}--------------------------------------------
public class Computer {
    public void powerOff(){
        System.out.println("关闭电脑");
    }
    public void powerOn(){
        System.out.println("打开电脑");
    }
    public void useDevice(IUSB usb){
        usb.openDevice();
        if (usb instanceof Mouse){
            Mouse mouse=(Mouse)usb;
            mouse.click();
        }
        if(usb instanceof KeyBoard){
            KeyBoard keyBoard=(KeyBoard) usb;
            keyBoard.input();

        }
        usb.closeDevice();

    }

    public static void main(String[] args) {
        Computer computer=new Computer();
        computer.powerOn();
        computer.useDevice(new KeyBoard());
        computer.useDevice(new Mouse());

        computer.powerOff();
    }
}

10,一个类可以同时继承抽象类和实现多个接口:

public abstract class Animal {
    protected String name;
    protected int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public abstract void eat();
}//抽象类
public interface IFly {
    void fly();
}//第一个接口
public interface IRunning {
    void run();
}//第二个接口
public interface ISwamming {
    void swam();
}//第三个接口
public  class Duck extends Animal implements ISwamming,IFly,IRunning{

    public Duck(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name+"吃鸭粮");
    }

    @Override
    public void fly() {
        System.out.println(this.name+"飞...");
    }

    @Override
    public void run() {
        System.out.println(this.name+"跑...");

    }

    @Override
    public void swam() {
        System.out.println(this.name+"游泳...");

    }
}
public static void eatfunc(Animal animal){
    animal.eat();
}
public static void runfunc(IRunning running){
    running.run();
}
eatfunc(new Fish("小鱼",3));

11, 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class

12,接口的实例:

想要比较对象中的成员变量的数值大小,因为它为引用数据类型,所以不能直接比较,此时需要一个接口,来实现比较,这个接口为Comparable<T>。

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

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

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

 @Override
    public int compareTo(Student o) {
        if(this.name.compareTo(o.name)>0){
            return 1;
        } else if (this.name.compareTo(o.name)==0) {
            return 0;
        }else {
            return -1;
        }//对方法的重写(姓名的比较)
    }

    @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 static void main1(String[] args) {
        Student student1=new Student("zhangsan",12);
        Student student2=new Student("lisi",10);
       if(student1.compareTo(student2)>0){
            System.out.println("student1>student2");
       }else{
            System.out.println("student1<=student2");

        }
    }
-------------------------------------------------
public static void mysort(Comparable[] comparable){
    for(int i=0;i<comparable.length-1;i++){
        for (int j=0;j<comparable.length-1-i;j++){
            if(comparable[j].compareTo(comparable[j+1])>0){
                Comparable tmp=comparable [j];
                comparable[j]=comparable[j+1];
                comparable[j+1]=tmp;
            }
        }
    }
}
public static void main(String[] args) {
    Student[]students=new Student[3];
    students[0]=new Student("zhangsan",12);
    students[1]=new Student("lisi",8);
    students[2]=new Student("wamgwu",10);
    System.out.println(Arrays.toString(students));
    //Arrays.sort(students);
     mysort(students);
    System.out.println(Arrays.toString(students));

}在 Arrays.sort();方法中会自动调用 compareTo 方法(所以在用sort比较时,也需要实现Comparable<T>接口). compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象. 然后比较当前对象和参数对象的大小关系.

(1)在接口Comparable<T>中有一个方法compareTo,需要对这个方法进行重写。

(2)Comparable接口有局限性,一旦写死了比较方式,后期就不能随意更改了

(3) 自己实现比较代码时,mysort(students);中的students,使用接口来接收的,所以自己实现比较代码时,也需要实现接口Comparable<T>,下图为Student类没有实现接口所报出的错误

也可以使用 Comparator<T>来实现比较。

public class Agecomparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age- o2.age;
    }
}//年龄比较器
public class Namecomparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}//名字比较器
public static void main1(String[] args) {
    Student student1=new Student("zhangsan",9);
    Student student2=new Student("lisi",10);


    Agecomparator agecomparator=new Agecomparator();
    int ret=agecomparator.compare(student1,student2);
    System.out.println(ret);

    Namecomparator namecomparator=new Namecomparator();
    int ret2=namecomparator.compare(student1,student2);
    System.out.println(ret2);
}
-------------------------------------------------------
public static void main(String[] args) {
    Student[]students=new Student[3];
    students[0]=new Student("zhangsan",12);
    students[1]=new Student("lisi",8);
    students[2]=new Student("wamgwu",10);
    Namecomparator namecomparator=new Namecomparator();
    System.out.println(Arrays.toString(students));
    Arrays.sort(students,namecomparator);
    System.out.println(Arrays.toString(students));
}//调用namecomparator来比较students。

13,深拷贝

  

class Student implements Cloneable{
必须实现cloneable接口(空接口、标记接口),只要实现这个克隆接口,证明这个类才能被实现clone
    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,因为object父类下面的方法为protected clone,父类,子类的包不同,不能直接访问,需要用到super
}

public class Text {
    public static void main(String[] args) throws CloneNotSupportedException{
        Student student1=new Student(10);异常问题
        Student student2=(Student) student1.clone();
        为向下转型,所以要强制类型转换
        
    }
}
-------------------------------------------------------------------------
class Money implements Cloneable{
    double money=12.5;

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

class Student implements Cloneable{
    int age;
    Money m=new Money();

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

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student tmp=(Student) super.clone();
        tmp.m=(Money) this.m.clone();
        return tmp;
    }
}

public class Text {
    public static void main(String[] args) throws CloneNotSupportedException{
        Student student1=new Student(10);
        Student student2=(Student) student1.clone();
        System.out.println(student1.m.money);
        System.out.println(student2.m.money);
        System.out.println("--------------");
        student2.m.money=100;
        System.out.println(student1.m.money);
        System.out.println(student2.m.money);
    }
}

浅拷贝:

浅拷贝克隆出的student2跟student1里面的数据一模一样,所以两者中的m都指向同一块空间(m为引用类型,存储的为地址)

深拷贝:

三,抽象类与接口的区别

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中 不能包含普通方法, 子类必须重写所有的抽象方法

四,Object类

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

class Person{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 @Override
    public boolean equals(Object obj) {
        Person person=(Person) obj;
        if(this.name.equals(person.name)){
            return true;
       }else return false;
   }//重写实现想要实现的功能
public static void main(String[] args) {
    Person person1=new Person("zhangsan",10);
    Person person2=new Person("zhangsan",9);
    System.out.println(person1.equals(person2));

}

因为person1和person2为引用类型,比较的地址,并不能实现想实现的功能,所以需要重写equals

hashcode方法(算出具体对象的位置):

Person person1=new Person("zhangsan",10);
Person person2=new Person("zhangsan",10);
System.out.println(person1.hashCode());
System.out.println(person2.hashCode());

此时输出的为两个不同的地址;

从代码上看,是两个不同的对象,但从逻辑上来说,名字,年龄一样,就是同一个人,所以想要这两个对象放到同一个位置,也就是想要两个哈希值是同样的,所以需要重写hashcode方法

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

以后只要是自定义类型,一定要重写hashcode方法和equals方法。

标签:JAVA,void,System,接口,age,详解,Student,println,public
From: https://blog.csdn.net/2302_81705247/article/details/137022599

相关文章

  • 数据结构——二叉搜索树详解
    一、二叉搜索树定义二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:1.非空左子树上所有节点的值都小于根节点的值。2.非空右子树上所有节点的值都大于根节点的值。3.左右子树也都为二叉搜索树。如下图所示:二、二叉搜索树的操作二叉搜索树结构:t......
  • Java基础语法(三)
    1.if语句1.1格式一 if(关系表达式){  语句体;   }执行流程    ①首先计算关系表达式的值    ②如果关系表达式的值为true就执行语句体    ③如果关系表达式的值为false就不执行语句体    ④继续执行后面的语句内容......
  • 函数是什么?C++函数详解!
    1、函数的声明和定义在复杂的程序中,如果全部的代码都写在main函数中,main函数体将非常庞大臃肿。把任务分工到其它的函数中,main函数只负责程序的核心流程,具体的任务由其它函数完成。这种思想就是模块化编程。声明和定义函数的语法:返回值的数据类型函数名(参数一的数据类型......
  • 淘宝item_sku-获取sku详细信息AIP接口(taobao.item_sku)布局技巧:3个技巧教你凸显商品sku
    淘宝的taobao.item_sku API接口是用于获取淘宝商品中SKU(StockKeepingUnit,库存量单位)的详细信息的。SKU通常代表一个商品的不同属性组合,比如颜色、尺码等。对于商家和消费者来说,了解SKU的详细信息是非常重要的,因为它可以帮助他们更准确地了解商品的具体属性和库存情况。通......
  • Java中的运算符使用
    运算符算术运算符+ - * / %++ --不要使用小数进行相等判断++:一元运算符,把原数据加1,再放回去。例:i++等价于 i=i+1;i++或++i单独出现时,没有区别,都是直接加1就行。i++;++i;当参与混合运算时,i++是先使用后加1,++i是先加1后使用。当一个计算公式中,出......
  • Springboot3基于SpringDoc实现接口分组功能
    问题最近在接触SpringBoot3,整合Swagger文档组件的过程中发现一个问题,通过springdoc.group-configs[0].display-name=示例接口配置分组名称在界面上面还是显示OpenAPIdefinition,如下图所示:查询了下官方文档,可以通过注入GroupedOpenApi对象实现接口分组描述信息展示,同时找到了一......
  • 卡码java基础课 | 21.图形的面积(面向对象)
    学习内容:面向对象的特性,封装、继承、多态。重点归纳:成员变量的定义:访问修饰符、数据类型、变量名。访问修饰符,private只能类内部使用,protected只能类内部和子类使用,public可以从任何地方访问。方法:访问修饰符、返回类型、方法名、参数列表。以及构造函数。1.封装:通过将属性设......
  • java打包docker镜像
    参考:https://blog.csdn.net/liuxianwen1990/article/details/136256490 1,把jar包复制/opt/test,cd到这个目录下 2,创建Dockerfile文件,jdk8版本vimDockerfileFROMopenjdk:8-jre-alpineCOPYdemo-0.0.1-SNAPSHOT.jardemo-0.0.1-SNAPSHOT.jarCMD["java","-jar&q......
  • 核心子方法6: registerBeanPostProcessors(beanFactory)方法详解
    先总结: 该方法用于创建并注册Bean后处理器,先获取创建beanFactory中的BeanPostProcessor, 排序后注册到beanFactory中(beanFactory.addBeanPostProcessor(postProcessor)), 用于后面创建bean对象时使用注: 这里不会调用执行BeanPostProcessor, 在创建bean对象getBean->doG......
  • 详解SSL证书系列(6)了解HTTP及网络基础
    使用HTTP协议访问Web你知道当我们在网页浏览器(比如Chrome)的地址栏中输入URL时,Web网页是如何呈现的吗? Web页面当然不会凭空显示出来。根据Web浏览器地址栏中指定的URL,Web浏览器从Web服务器端获取文件资源等信息,从而显示出Web页面。像这种通过发送请求然后获取服务器资源的Web......