当前位置:   article > 正文

【Java】抽象类&接口_抽象类实现接口

抽象类实现接口

目录

1.抽象类

2.接口

2.1实现多个接口

2.2接口之间的关系

2.3接口使用实例

2.3.1Comparable接口

2.3.2Comparator接口

2.3.2Clone接口

2.4抽象类与接口的区别


1.抽象类

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

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

注意

1> 使用 abstract 修饰;

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

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

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

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

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

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

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

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

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

  1. abstract class Shape { //抽象类
  2. public int a;//普通成员变量
  3. public void print() { //普通成员方法
  4. System.out.println("Shape");
  5. }
  6. public abstract void draw(); //抽象方法
  7. }
  8. class Cycle extends Shape { //普通类
  9. @Override //普通类继承抽象类后要重写抽象类中的抽象方法
  10. public void draw() {
  11. System.out.println("○");
  12. }
  13. }
  14. abstract class Flower extends Shape {
  15. //抽象类继承抽象类,可以不重写父类的抽象方法
  16. abstract public void printf();//抽象方法
  17. }
  18. class Square extends Flower {
  19. @Override //见注意事项6
  20. public void draw() {
  21. System.out.println("□");
  22. }
  23. @Override
  24. public void printf() {
  25. System.out.println("❀");
  26. }
  27. }

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

  1. interface IShape { //接口
  2. //成员方法默认为public abstract修饰,顾下列方法均为抽象方法
  3. public abstract void draw1();//抽象方法不可实现,public abstract可省略
  4. public void draw2();//抽象方法不可实现,public可省略
  5. public static void draw3() { //静态方法可以实现
  6. System.out.println("draw3");
  7. }
  8. default public void draw4() { //被default修饰的方法可以实现
  9. System.out.println("draw4");
  10. }
  11. }
  12. class Cycle implements IShape { //Cycle类实现了IShape接口
  13. @Override //重写接口中的抽象方法
  14. public void draw1() {
  15. System.out.println("○");
  16. }
  17. @Override //重写接口中的抽象方法
  18. public void draw2() {
  19. System.out.println("□");
  20. }
  21. }
  22. class Rect implements IShape { //同上
  23. @Override
  24. public void draw1() {
  25. System.out.println("□");
  26. }
  27. @Override
  28. public void draw2() {
  29. System.out.println("○");
  30. }
  31. }
  32. public class Test {
  33. public static void drawMap(IShape shape) { //多态
  34. shape.draw1();
  35. }
  36. public static void main(String[] args) {
  37. //IShape iShape = new IShape();//接口无法实例化自己
  38. IShape iShape1 = new Cycle();
  39. IShape iShape2 = new Rect();//向上转型
  40. drawMap(new Cycle());
  41. drawMap(new Rect());
  42. }
  43. }

2.1实现多个接口

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

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

  1. interface IFlying { //接口1
  2. void fly();
  3. }
  4. interface ISwimming { //接口2
  5. void swim();
  6. }
  7. interface IRunning { //接口3
  8. void run();
  9. }
  10. abstract class Animal { //抽象父类
  11. public String name;
  12. public int age;
  13. public Animal(String name, int age) { //带两个参数的构造方法
  14. this.name = name;
  15. this.age = age;
  16. }
  17. public abstract void eat(); //抽象方法
  18. }
  19. class Dog extends Animal implements IRunning,ISwimming{ //子类1
  20. public Dog(String name, int age) { //子类的构造方法
  21. super(name, age);
  22. }
  23. @Override //重写父类和接口的抽象方法
  24. public void swim() {
  25. System.out.println(this.name+"正在狗刨");
  26. }
  27. @Override
  28. public void run() {
  29. System.out.println(this.name+"正在跑");
  30. }
  31. @Override
  32. public void eat() {
  33. System.out.println(this.name+"正在吃狗粮");
  34. }
  35. }
  36. class Bird extends Animal implements IFlying { //子类2
  37. public Bird(String name, int age) { //子类的构造方法
  38. super(name, age);
  39. }
  40. @Override //重写父类和接口的抽象方法
  41. public void fly() {
  42. System.out.println(this.name+"正在飞");
  43. }
  44. @Override
  45. public void eat() {
  46. System.out.println(this.name+"正在吃虫子");
  47. }
  48. }
  49. public class Test {
  50. public static void testEat(Animal animal) { //多态
  51. animal.eat();
  52. }
  53. public static void testFly(IFlying iFlying) { //多态
  54. iFlying.fly();
  55. }
  56. public static void testRun(IRunning running) { //多态
  57. running.run();
  58. }
  59. public static void testSwim(ISwimming iSwimming) { //多态
  60. iSwimming.swim();
  61. }
  62. public static void main(String[] args) {
  63. testEat(new Bird("小鸟",3));
  64. testEat(new Dog("小狗",3));
  65. testFly(new Bird("小小鸟",2));
  66. testRun(new Dog("小小狗",2));
  67. testSwim(new Dog("小小小狗",1));
  68. }
  69. }

2.2接口之间的关系

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

  1. interface A {
  2. void testA();
  3. }
  4. interface B {
  5. void testB();
  6. }
  7. interface C extends A,B { //此时C接口不仅有自己的功能,还有A接口和B接口的功能
  8. void testC();
  9. }
  10. class D implements C { //ABC中的抽象方法都要重写
  11. @Override
  12. public void testA() {
  13. }
  14. @Override
  15. public void testB() {
  16. }
  17. @Override
  18. public void testC() {
  19. }
  20. }

2.3接口使用实例

2.3.1Comparable接口

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

  1. import java.util.Arrays;
  2. class Student implements Comparable<Student>{ //当对自定义类型进行比较时,一定要实现可比较的接口
  3. public String name;
  4. public int age;
  5. public double score;
  6. public Student(String name, int age, double score) { //带三个参数的构造方法
  7. this.name = name;
  8. this.age = age;
  9. this.score = score;
  10. }
  11. @Override //重写Comparable接口中的抽象方法
  12. public int compareTo(Student o) { //按年龄排序
  13. /*if (this.age - o.age > 0) {
  14. return 1;
  15. } else if (this.age - o.age == 0) {
  16. return 0;
  17. }else {
  18. return -1;
  19. }*/
  20. return this.age - o.age;
  21. }
  22. }
  23. public class Test {
  24. //模拟实现冒泡排序
  25. public static void bubbleSort(Comparable[] comparables) { //传入Comparable类型(实现了可比较接口)的数组
  26. for (int i = 0; i < comparables.length-1; i++) {
  27. for (int j = 0; j < comparables.length-1-i; j++) {
  28. //if (comparables[j]>comparables[j+1]) //无法直接比较
  29. if(comparables[j].compareTo(comparables[j+1]) > 0) { //使用重写的compareTo方法比较
  30. Comparable tmp = comparables[j];
  31. comparables[j] = comparables[j+1];
  32. comparables[j+1] = tmp;
  33. }
  34. }
  35. }
  36. }
  37. public static void main(String[] args) {
  38. Student[] array = new Student[2];
  39. array[0] = new Student("zhangsan",20,88.8);
  40. array[1] = new Student("lisi",18,90);
  41. bubbleSort(array); //冒泡排序
  42. System.out.println("排序后:"+Arrays.toString(array));
  43. }
  44. public static void main2(String[] args) {
  45. Student student1 = new Student("xiaoming",14,98.5);
  46. Student student2 = new Student("xiaohong",16,59.9);
  47. int ret = student1.compareTo(student2);
  48. System.out.println(ret); //-1
  49. }
  50. public static void main1(String[] args) {
  51. Student[] array = new Student[3];
  52. array[0] = new Student("zhangsan",20,88.8);
  53. array[1] = new Student("lisi",18,90);
  54. array[2] = new Student("wangwu",21,68.9);
  55. System.out.println("排序前:"+ Arrays.toString(array));
  56. Arrays.sort(array); //Java自带的方法
  57. System.out.println("排序后:"+ Arrays.toString(array));
  58. }
  59. }

2.3.2Comparator接口

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

  1. import java.util.Comparator;
  2. class Student{
  3. public String name;
  4. public int age;
  5. public double score;
  6. public Student(String name, int age, double score) {
  7. this.name = name;
  8. this.age = age;
  9. this.score = score;
  10. }
  11. }
  12. class AgeComparator implements Comparator<Student> { //比较年龄
  13. @Override
  14. public int compare(Student o1, Student o2) {
  15. return o1.age - o2.age;
  16. }
  17. }
  18. class ScoreComparator implements Comparator<Student> { //比较成绩
  19. @Override
  20. public int compare(Student o1, Student o2) {
  21. return (int)(o1.score - o2.score);//score为double类型,需要强转为int类型
  22. }
  23. }
  24. public class Test {
  25. public static void main(String[] args) {
  26. Student student1 = new Student("xiaoming",14,98.5);
  27. Student student2 = new Student("xiaohong",16,59.9);
  28. AgeComparator ageComparator = new AgeComparator();
  29. int ret = ageComparator.compare(student1,student2);
  30. System.out.println(ret);//-2
  31. ScoreComparator scoreComparator = new ScoreComparator();
  32. int ret2 = scoreComparator.compare(student1,student2);
  33. System.out.println(ret2);//38
  34. }
  35. }

2.3.2Clone接口

  1. class Student implements Cloneable { //实现Cloneable接口
  2. public int age;
  3. public Student(int age) {
  4. this.age = age;
  5. }
  6. @Override
  7. public String toString() {
  8. return "Student{" +
  9. "age=" + age +
  10. '}';
  11. }
  12. @Override
  13. protected Object clone() throws CloneNotSupportedException { //异常
  14. return super.clone();//子类重写的Object只是调用了父类的clone方法
  15. }
  16. }
  17. public class Test {
  18. public static void main(String[] args) throws CloneNotSupportedException {
  19. Student student1 = new Student(18);
  20. Student student2 = (Student) student1.clone();//向下转型,clone类型为Object,需强转为Student
  21. System.out.println(student1);//Student{age=18}
  22. System.out.println(student2);//Student{age=18} 克隆成功
  23. }
  24. }

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

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

//浅拷贝 

  1. class Money {
  2. public double money;
  3. }
  4. class Student implements Cloneable { 实现Cloneable接口
  5. public int age;
  6. public Money m = new Money();
  7. public Student(int age) {
  8. this.age = age;
  9. }
  10. @Override //重写接口中的抽象方法
  11. protected Object clone() throws CloneNotSupportedException {
  12. return super.clone();
  13. }
  14. }
  15. public class Test {
  16. public static void main(String[] args) throws CloneNotSupportedException {
  17. Student student1 = new Student(18);
  18. student1.m.money = 9.15;
  19. Student student2 = (Student) student1.clone();//克隆student1
  20. System.out.println(student1.m.money);//9.15
  21. System.out.println(student2.m.money);//9.15
  22. student1.m.money = 10;//更改student1
  23. System.out.println(student1.m.money);//10 按理说只有student1变
  24. System.out.println(student2.m.money);//10 但是实际上两个都变了
  25. //这就是浅拷贝,没有克隆当前对象内更深层的变量
  26. }
  27. }

//深拷贝

  1. class Money implements Cloneable { //实现Cloneable接口
  2. public double money;
  3. @Override //重写接口中的抽象方法
  4. protected Object clone() throws CloneNotSupportedException {
  5. return super.clone();
  6. }
  7. }
  8. class Student implements Cloneable { //实现Cloneable接口
  9. public int age;
  10. public Money m = new Money();
  11. public Student(int age) {
  12. this.age = age;
  13. }
  14. @Override //重写接口中的抽象方法
  15. protected Object clone() throws CloneNotSupportedException {
  16. Student tmp = (Student) super.clone();//先克隆当前对象
  17. tmp.m = (Money) this.m.clone();//再克隆当前对象里更深层的变量
  18. return tmp;
  19. }
  20. }
  21. public class Test {
  22. public static void main(String[] args) throws CloneNotSupportedException {
  23. Student student1 = new Student(18);
  24. student1.m.money = 9.15;
  25. Student student2 = (Student) student1.clone();//克隆student1
  26. System.out.println(student1.m.money);//9.15
  27. System.out.println(student2.m.money);//9.15
  28. student1.m.money = 10;//更改student1
  29. System.out.println(student1.m.money);//10 深拷贝,只修改了student1
  30. System.out.println(student2.m.money);//9.15 不影响student2内的值
  31. }
  32. }

2.4抽象类与接口的区别

区别

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

Over!五一结束啦~~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/180499?site
推荐阅读
相关标签
  

闽ICP备14008679号