目录

一、抽象类

1.1 概念语法

1.2 抽象类的特性

二、接口

2.1 概念

2.2 接口的使用

2.3 实现多个接口

2.4 接口之间的继承(功能的拓展)

2.5 自定义类型排序

2.6 Clonable接口和深拷贝

2.7 抽象类和接口的区别

三、Object类

3.1 对象比较equals方法

3.2 hashcode方法

一、抽象类

 1.1 概念语法

  • 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
  • 一个类被abstract修饰,称为抽象类,被abstract修饰的方法叫做抽象方法。
abstract class Shape{//抽象方法public abstract void draw();
}

1.2 抽象类的特性

  • 在抽象类当中,可以有和普通类一样的方法、成员。最突出的区别就是抽象类不能实例化对象。

    abstract class Shape{public int a;public static int b;public void fun(){}//抽象方法public abstract void draw();
    }
  • 抽象类虽然不能实例化,但是可以被继承(抽象类就是要被继承的)。
  • 当一个普通类继承了抽象类,并且这个抽象类当中含有抽象方法,那么就要重写这个抽象方法,否则编译器不能通过编译。
    abstract class Shape{//抽象方法public abstract void draw();
    }class React extends Shape{@Overridepublic void draw() {}
    }
    public class Test1 {public static void main(String[] args) {}
    }
    
  • 如果一个抽象类A继承另一个抽象类B,那么此时抽象类A可以不重写B中的抽象方法。
  • 抽象方法不能被private、static、final的关键字修饰的,因为抽象方法是要被继承的。

抽象类的作用 

  • 抽象类的作用就是相当于多了一层编译器的校验,在实际开发中是非常有意义的。

二、接口

2.1 概念

在生活中接口非常常见,例如:电脑上USB接口,所有USB都可以插入这个接口,不管是鼠标、键盘、U盘都可以插入。

在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型

2.2 接口的使用

  • 语法规则:

public interface 接口名称{

           // 抽象方法
           public abstract void method1(); // public abstract 是固定搭配,可以不写

}

  • 接口的使用 (接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。)

public class 类名称 implements 接口名称{
   // ...
}

注:接口名称一般以大写的  I  开头

  •  接口的特性:
public  interface IShape {public int a = 1;int b = 2;final int c = 3;default void test(){}public void fun();
}class React implements IShape{@Overridepublic void fun() {}
}
  1. 接口中的成员变量,默认都是由 public static final 修饰的。
  2. 接口当中的成员方法,默认都是抽象方法,由  public abstract  修饰的
  3. 接口中的普通成员方法,是不能有具体的实现的,如果要有具体的实现,必须加上default 修饰。
  4. 接口当中可以有静态成员方法,,但无论是静态方法还是 default方法,都是由public修饰的。
  5. 接口是不能实例化的
  6. 一个接口可以引用具体实现类的,向上转型。
  7. 接口当中不能有静态代码块、实例代码块、构造方法
  8. 如果一个抽象类实现一个接口,那这个抽象类就可以不重写抽象方法,但是还有其他类继承这个抽象类,那么还是要重写抽象方法的。

2.3 实现多个接口

在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承,但是一个类可以实现多个接口。

例如:

我们先创建一个动物类:

class Animal{public String name;public Animal(String name) {this.name = name;}
}

再创建几个动物行为的接口:

interface fly{void fly();
}interface running{void running();
}
interface ISwimming{void swim();
}

然后创建具体的动物;

狗是用四条腿跑的:

class Dog extends Animal implements IRunning{public Dog(String name) {super(name);}@Overridepublic void run() {System.out.println(name + "正在用四条腿跑!");}
}

小鸟是用翅膀飞的:

class Bird extends Animal implements IFly{public Bird(String name) {super(name);}@Overridepublic void fly() {System.out.println(name+"正在用翅膀飞");}
}

鱼是用尾巴在水里游的:

class Fish extends Animal implements ISwimming{public Fish(String name) {super(name);}@Overridepublic void swim() {System.out.println(name + "正在水里用尾巴游");}
}

而鸭子既可以跑又可以飞还可以游泳:

class Duck extends Animal implements ISwimming,IFly,IRunning{public Duck(String name) {super(name);}@Overridepublic void fly() {System.out.println(name+"正在用翅膀飞");}@Overridepublic void run() {System.out.println(name +"正在用鸭掌跑");}@Overridepublic void swim() {System.out.println(name+"正在用鸭掌游泳");}
}
public class Test2 {public static void fly(IFly iFly){iFly.fly();}public static void swim(ISwimming iSwimming){iSwimming.swim();}public static void run(IRunning iRunning){iRunning.run();}public static void main(String[] args) {fly(new Duck("唐老鸭"));run(new Duck("唐老鸭"));swim(new Duck("唐老鸭"));}
}

注:

  1.  一个类实现多个接口时,每个接口的抽象方法都要重写,除非是抽象类可以不用重写。
  2. 接口表达的含义是具有xxx特性。

2.4 接口之间的继承(功能的拓展)

接口和接口之间可以达到多继承:

interface IFly{void fly();
}interface IRunning{void run();
}
interface ISwimming{void swim();
}
interface IAnimal extends IRunning,IFly,ISwimming{}

2.5 自定义类型排序

Comparable接口可以用来排序我们自定义类型的排序:

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;}@Overridepublic int compareTo(Student o) {return this.age - o.age;}}public class Test {public static void main(String[] args) {Student student = new Student("小明",10,100);Student student1 = new Student("小红",13,99);if (student.compareTo(student1) > 0){System.out.println("student > student1");}else if(student.compareTo(student1) == 0){System.out.println("student = student1");}else{System.out.println("student < student2");}}
}

注:

自定义数据牵扯到比较大小,需要指明比较大小的数据类型,在我们重写的compareTo方法中实现的。

上面这种情况我们就只能比较年龄,如果还想比较其他数据的话就必须进行修改,其实我们实现一个比较器:

年龄比较器:

class AgeComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return o1.age - o2.age;}
}
public class Test {public static void main(String[] args) {Student student = new Student("小明",10,100);Student student1 = new Student("小红",13,99);AgeComparator ageComparator = new AgeComparator();int ret = ageComparator.compare(student,student1);if (ret > 0){System.out.println("student > student1");}else if(ret == 0){System.out.println("student = student1");}else{System.out.println("student < student2");}
}

分数比较器:

class ScoreComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return (int) (o1.score - o2.score);}
}

对于自定义类型排序我们还可以使用Array.sort排序:

class ScoreComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return (int) (o2.score - o1.score);}
}public class Test {public static void main(String[] args) {Student[] students = new Student[3];students[0] = new Student("小明",10,100);students[1] = new Student("小红",12,50);students[2] = new Student("小花",13,76);ScoreComparator scoreComparator = new ScoreComparator();Arrays.sort(students,scoreComparator);System.out.println(Arrays.toString(students));}
}

2.6 Clonable接口和深拷贝

Clonable接口克隆一个对象就是产生这个对象的副本:

class Person implements Cloneable{public int age = 10;@Overridepublic String toString() {return "Person{" +"age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class Test {public static void main(String[] args) throws CloneNotSupportedException{Person person = new Person();Person person1 = (Person) person.clone();System.out.println(person1);}
}


 当我们修改这个副本的值时,主体不会受到影响:

其内存布局如下:


但是当我们再定义一个钱类,在人类里面对它实例化后,并且将克隆副本的钱的值修改,再打印就会发现主体和副本钱的值都修改:

class Money{public int money = 20;
}class Person implements Cloneable{public int age = 10;public Money m = new Money();
}

 它的内存分布如下:

这个就是浅拷贝,只是拷贝了Money的地址,并没有创建一个新的副本。我们可以给Money也实现一个接口,从而实现深拷贝:

2.7 抽象类和接口的区别

  1. 抽象类是被abstract修饰,其方法为抽象方法且不用具体实现,与普通类最大的区别就是不能实例化;接口也不能实例化,其成员方法默认为抽象方法。
  2. 抽象类被继承后要重写抽象方法(extends),接口被实现后也要重写抽象方法(interface);
  3. 一个子类只能继承一个抽象类,一个子类可以实现多个接口;
  4. 一个抽象类可以实现多个接口,接口不能继承抽象类,但是接口可以使用extends关键字继承多个接口。
  5. 子类继承抽象类,重写抽象方法时其限定修饰符权限必须大于抽象方法的修饰符;而接口就是public;

三、Object类

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

class Person{}
class Student{}
public class Test {public static void main(String[] args) {Object o = new Person();Object o1 = new Student();}
}

也可以方法传参接收:

class Person{public String name = "hello";@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +'}';}
}
class Student{}
public class Test {public static void func(Object o){String str = o.toString();System.out.println(str);}public static void main(String[] args) {func(new Student());func(new Person());}public static void main1(String[] args) {Object o = new Person();Object o1 = new Student();}
}

3.1 对象比较equals方法

class Person{public int age;public Person(int age) {this.age = age;}@Overridepublic 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;}}
public class Test {public static void main(String[] args) {Person person = new Person(10);Person person1 = new Person(10);System.out.println(person.equals(person1));}

注:比较对象中内容是否相同的时候,一定要重写equals方法。

3.2 hashcode方法

hashcode()这个方法帮我们算出一个具体对象的地址,也可以称为内存地址,然后将其打印出来。

class Person{public int age;public Person(int age) {this.age = age;}@Overridepublic int hashCode() {return Objects.hash(age);}
}public class Test {public static void main(String[] args) {Person person = new Person(10);Person person1 = new Person(10);System.out.println(person1.hashCode());System.out.println(person2.hashCode());}

  • 我们可以重写hashcode()方法,来实现对相同年龄位置定位相同的位置,所以运行结果是相同的数值。

【迷人的爪哇】——抽象类和接口相关推荐

  1. 不允许使用抽象类类型的对象怎么办_Java基础——面试官:你来说说抽象类和接口的区别...

    无论你是新手Java 程序员,还是老手程序员,可能在实际开发中很少自己写抽象类. 但是抽象类在某些时候的功能很强大,可以保证子类中百分百实现父类中的方法 -- 普通类的弊端,消除子类的冗余代码 -- ...

  2. php 抽象类 接口 区别,PHP中抽象类、接口的区别与选择分析

    本文实例分析了PHP中抽象类.接口的区别与选择.分享给大家供大家参考,具体如下: 区别: 1.对接口的使用是通过关键字implements.对抽象类的使用是通过关键字extends.当然接口也可以通过 ...

  3. C#中抽象类和接口的区别

    一.抽象类:       抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆 ...

  4. java中抽象接口_一篇文章让你彻底理解java中抽象类和接口

    相信大家都有这种感觉:抽象类与接口这两者有太多相似的地方,又有太多不同的地方.往往这二者可以让初学者摸不着头脑,无论是在实际编程的时候,还是在面试的时候,抽象类与接口都显得格外重要!希望看完这篇博客文 ...

  5. 类、抽象类、接口之间的区别

    目录 1.类与抽象类的异同之处 (1)类和抽象类的区别 (2)类和抽象类的相同之处 2.接口与类的异同之处 (1)接口与类相似点 (2)接口与类的区别 (3)接口特性 3.抽象类和接口的区别 1.类与 ...

  6. Java 抽象类与接口的区别

    接口和抽象类有什么区别 你选择使用接口和抽象类的依据是什么? 接口和抽象类的概念不一样.接口是对动作的抽象,抽象类是对根源的抽象 抽象类表示的是,这个对象是什么.接口表示的是,这个对象能做什么.比如, ...

  7. java 接口工程_Java工程师(15)抽象类与接口

    抽象类 思考下面程序潜在的问题 交通工具中定义了4个方法,其中行驶方法内部会依次调用启动.加速.停止方法.由于不同的交通工具,启动的方式差异很大,所以交通工具类中并不实现该方法,而是将其交给子类实现. ...

  8. 《Java技术》第三次作业--面向对象——继承、抽象类、接口

    1.阅读下面程序,分析是否能编译通过?如果不能,说明原因.应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来? class Grandparen ...

  9. 抽象类和接口的联系与区别

    抽象类和接口联系与区别 关键字: 抽象类与接口的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的 ...

最新文章

  1. 优雅还不够,简洁才高效!——用NValidator一句话搞定客户端检测
  2. nhibernate之many-to-many的性能
  3. 什么是springboot框架
  4. linux局部变量特殊字符替换,变量,全局变量,环境变量,特殊符号、管道符命令:cut、sort、uniq、wc、tee、tr、sp...
  5. excel 表格lookup 的操作
  6. 2021年德国汽车产量预计同比锐减18%
  7. 前端埋点的缺点_【埋点学习埋点质量】埋点的框架设计及其准确性
  8. Unicode官网Code Charts下载。
  9. 十进制经纬度格式转换度分格式
  10. 高质量论文配图配色(附RGB值及16进制码)
  11. deepin linux 安装 磁盘管理,deepin安装教程
  12. 趣挨踢 | 只有挨踢人才能读懂的西游记
  13. AMap(地图组成与名词解释)
  14. c语言处理文本断句空格,c语言怎么断句
  15. php 文字弹幕效果代码,视频弹幕特效代码
  16. 百汇BCR:通过K线可以判断出外汇市场有哪些形态?
  17. 支付宝生活号对接-----(一)授权
  18. 操作系统2022简答8选4
  19. 关于IIC总线的若干问题
  20. 【手写信息搜集工具】ThunderSearch 闪电搜索器

热门文章

  1. 金融行业管理解决方案
  2. 分析一下 原型模式的 UML 类图 。 复制对象, 深浅拷贝 月经贴 ,请回避
  3. 加州理工大学伯克利分计算机科学,加州理工大学伯克利分校专业有什么?
  4. java代码实现99乘法表
  5. 双拼输入法,设计方案
  6. 阿里OCR扫描字识别demo
  7. 一套开源免费的OA办公管理系统源码,带小程序、生成APP
  8. 井蛙不可以语于海者,拘于虚也;夏虫不可以语于冰者,笃于时也
  9. 函数的返回值 return(基础)
  10. 逻辑是对的不一定推出正确的结果