• 抽象类和接口


    目录

    抽象类

    抽象类使用abstract修饰类

    抽象类当中可以包含普通类所能包含的成员

    抽象类和普通类不一样的是,抽象类当中可以包含抽象方法。

    抽象类方法是使用abstract修饰的,这个方法没有具体的实现

    不能实例化抽象类

    抽象类存在的意义是为了被继承

    抽象类的方法不能是私有的(private),要满足重写的规则。

    抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员

    接口

    1.使用interface来修饰接口

    2.接口当中的成员方法不能有具体的实现。

     在接口中抽象方法默认是public abstract的方法

    接口不可以被实例化,也就是说接口不能有静态代码块和构造方法

    可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。

    接口的使用

    实现多个接口

     抽象类和接口的区别:

    Object类

    toString

    equals


    抽象类

    抽象类使用abstract修饰类

    抽象类当中可以包含普通类所能包含的成员

    抽象类和普通类不一样的是,抽象类当中可以包含抽象方法

    抽象类方法是使用abstract修饰的,这个方法没有具体的实现

    1. abstract class Shape{
    2. public int a;
    3. public abstract void draw();
    4. public void func(){
    5. }
    6. }

    不能实例化抽象类

    1. public class Test {
    2. public static void main(String[] args) {
    3. Shape shape = new Shape();//报错
    4. }
    5. }

    抽象类存在的意义是为了被继承

    如果一个普通类继承了抽象类,此时必须重写抽象类中的方法。

    1. class Rect extends Shape{
    2. @Override
    3. public void draw() {
    4. System.out.println("矩形");
    5. }
    6. }

    一个抽象类A继承一个抽象类B,此时不需要重写B中的抽象方法,但当A被继承时,还是要重写B中的抽象方法。

    抽象类的方法不能是私有的(private),要满足重写的规则。

    抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员

    接口

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

    1.使用interface来修饰接口

    2.接口当中的成员方法不能有具体的实现。

    1. interface IShape {
    2. public abstract void func1();
    3. public void func2(){
    4. //报错
    5. }
    6. }

     在接口中抽象方法默认是public abstract的方法

    从JDK1.8开始,允许有方法的实现,但是这个方法必须是有default修饰的

    可以实现有静态方法

    成员变量默认是public static final修饰的,子类如果重写抽象方法必须由public修饰

    1. interface IShape {
    2. public static final int a = 10;
    3. int b = 20;//默认也是public static final修饰的
    4. public abstract void func1();
    5. void func();//默认也是public abstract修饰的
    6. public void func2(){
    7. //报错
    8. }
    9. default public void func3(){
    10. System.out.println("默认方法");
    11. }
    12. public static void func4(){
    13. System.out.println("static修饰的方法");
    14. }
    15. }

    接口不可以被实例化,也就是说接口不能有静态代码块和构造方法

    1. public static void main(String[] args) {
    2. IShape ishape = new IShape();//报错
    3. }

    可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。

    1. class A implements IShape{
    2. public void func1(){
    3. System.out.println("重写抽象方法");
    4. }
    5. }

    接口的使用

    请实现笔记本电脑使用 USB 鼠标、 USB 键盘的例子
    1. USB 接口:包含打开设备、关闭设备功能
    1. //USB接口
    2. public interface USB {
    3. void openDevice();
    4. void closeDevice();
    5. }
    2. 鼠标类:实现 USB 接口,并具备点击功能
    1. public class Mouse implements USB{
    2. @Override
    3. public void openDevice() {
    4. System.out.println("打开鼠标");
    5. }
    6. @Override
    7. public void closeDevice(){
    8. System.out.println("关闭鼠标");
    9. }
    10. public void click(){
    11. System.out.println("鼠标点击");
    12. }
    13. }

    3. 键盘类:实现USB接口,并具备输入功能

    1. public class KeyBoard implements USB {
    2. @Override
    3. public void openDevice() {
    4. System.out.println("打开键盘");
    5. }
    6. @Override
    7. public void closeDevice() {
    8. System.out.println("关闭键盘");
    9. }
    10. public void inPut(){
    11. System.out.println("键盘输入");
    12. }
    13. }

    4. 笔记本类:包含开机功能、关机功能、使用 USB 设备功能
    1. public class Computer{
    2. public void powerOn(){
    3. System.out.println("打开笔记本电脑");
    4. }
    5. public void powerOff(){
    6. System.out.println("关闭笔记本电脑");
    7. }
    8. public void useDevice(USB usb){
    9. usb.openDevice();
    10. if(usb instanceof Mouse){
    11. Mouse mouse = (Mouse) usb;
    12. mouse.click();
    13. }
    14. if(usb instanceof KeyBoard){
    15. KeyBoard keyboard = (KeyBoard) usb;
    16. keyboard.inPut();
    17. }
    18. usb.closeDevice();
    19. }
    20. }

    测试:

    1. //测试
    2. public class TestUsb {
    3. public static void main(String[] args){
    4. Computer computer = new Computer();
    5. computer.powerOn();
    6. computer.useDevice(new Mouse());
    7. computer.useDevice(new KeyBoard());
    8. computer.powerOff();
    9. }
    10. }

    实现多个接口

    一个类可以实现多个接口,使用implements 用逗号隔开。(可以解决多继承的问题)
    1. interface A{
    2. void func1();
    3. }
    4. interface B{
    5. void func2();
    6. }
    7. class C implements A,B{
    8. @Override
    9. public void func1() {
    10. System.out.println(1);
    11. }
    12. @Override
    13. public void func2() {
    14. System.out.println(2);
    15. }
    16. }

    接口实现多继承和多态简单实例

    1. class Animal{
    2. public String name;
    3. public int age;
    4. public Animal(String name,int age){
    5. this.name = name;
    6. this.age = age;
    7. }
    8. public void eat(){
    9. System.out.println("吃饭");
    10. }
    11. }
    12. interface IRuning{
    13. void runing();
    14. }
    15. interface ISwimming{
    16. void swimming();
    17. }
    18. interface IFly{
    19. void fly();
    20. }
    21. class Dog extends Animal implements IRuning,ISwimming{
    22. public Dog(String name,int age){
    23. super(name,age);
    24. }
    25. @Override
    26. public void runing() {
    27. System.out.println(name+"正在跑");
    28. }
    29. @Override
    30. public void swimming() {
    31. System.out.println(name+"正在游泳");
    32. }
    33. }
    34. class Duck extends Animal implements IRuning,ISwimming,IFly{
    35. public Duck(String name,int age){
    36. super(name,age);
    37. }
    38. @Override
    39. public void runing() {
    40. System.out.println(name+"正在跑");
    41. }
    42. @Override
    43. public void swimming() {
    44. System.out.println(name+"正在游泳");
    45. }
    46. @Override
    47. public void fly() {
    48. System.out.println(name+"正在飞");
    49. }
    50. }
    51. public class Test {
    52. public static void walk(IRuning iruning){
    53. iruning.runing();//多态
    54. }
    55. public static void main(String[] args) {
    56. walk(new Dog("小黑",2));
    57. walk(new Duck("可达鸭",3));
    58. }
    59. }

     继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性

    有了接口之后 , 类的使用者就不必关注具体类型 , 而只关注某个类是否具备某种能力
    1. class Robot implements IRuning{
    2. @Override
    3. public void runing() {
    4. System.out.println("机器人正在跑步");
    5. }
    6. }
    7. public class Test {
    8. public static void walk(IRuning iruning){
    9. iruning.runing();
    10. }
    11. public static void main(String[] args) {
    12. walk(new Dog("小黑",2));
    13. walk(new Duck("可达鸭",3));
    14. walk(new Robot());
    15. }
    16. }

    机器人不是动物,但仍然可以实现多态,因为接口只关注某个类是否具有某种能力。机器人有跑步的能力,那他就可以实现。

     抽象类和接口的区别:

    抽象类可以包含普通字段和成员,接口中不能包含普通方法,子类必须重写所有的抽象方法

    抽象方法由普通类(普通字段和方法)和抽象方法组成

    接口由抽象方法和全局常量组成

    使用extends继承抽象类,使用implements关键字实现接口

    一个抽象类可以实现若干个接口,接口不能继承抽象类,接口可以使用extends继承多个父类接口

    一个子类只能继承一个抽象类,一个子类可以实现多个接口

    Object类

    Object类是所以类的父类,我们自己写的类就算没有写extends Object,默认也是继承的

    1. class Teacher{
    2. }
    3. class Student{
    4. }
    5. public class Test2 {
    6. public static void func(Object object){
    7. }
    8. public static void main(String[] args) {
    9. func(new Student());//向上转型,不报错
    10. func(new Teacher());
    11. }
    12. }

    Object类当中的一些方法:

    toString

    输出对象的名称,和@符号后面跟一串16进制数字,该数字是由hashCode这个方法产生的 

    equals

    Java 中, == 进行比较时:
    如果==左右两侧是基本类型变量,比较的是变量中值是否相同
    如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同
    如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的
    Object类中的equals方法

     可见Object类中的equals是使用引用中的地址来进行比较的

    1. class Person{
    2. String name;
    3. int age;
    4. public Person(String name,int age){
    5. this.name = name;
    6. this.age = age;
    7. }
    8. }
    9. public class Test3 {
    10. public static void main(String[] args) {
    11. Person per1 = new Person("zhangsan",20);
    12. Person per2 = new Person("zhangsan",20);
    13. int a = 10;
    14. int b = 10;
    15. System.out.println(a==b);
    16. System.out.println(per1==per2);
    17. System.out.println(per1.equals(per2));
    18. }
    19. }

    Person类重写equals方法:

    1. class Person{
    2. String name;
    3. int age;
    4. public Person(String name,int age){
    5. this.name = name;
    6. this.age = age;
    7. }
    8. @Override
    9. public boolean equals(Object obj) {
    10. if(obj==null){
    11. return false;
    12. }
    13. if(this == obj){
    14. return true;
    15. }
    16. if(!(obj instanceof Person)){
    17. return false;
    18. }
    19. Person per = (Person) obj;
    20. if(this.name.equals(per.name) && this.age == per.age){
    21. return true;
    22. }else{
    23. return false;
    24. }
    25. }
    26. }
    27. public class Test3 {
    28. public static void main(String[] args) {
    29. Person per1 = new Person("zhangsan",20);
    30. Person per2 = new Person("zhangsan",20);
    31. int a = 10;
    32. int b = 10;
    33. System.out.println(a==b);
    34. System.out.println(per1==per2);
    35. System.out.println(per1.equals(per2));
    36. }
    37. }

  • 相关阅读:
    Oracle 修改Varchar2类型长度限制
    nodejs+vue菜谱美食食谱网站系统
    MobPush开发过程常见问题
    机器学习(10)---特征选择
    记录一次较为完整的Jenkins发布流程
    【JDBC篇】preparedStatement功能介绍
    简单工厂模式
    Academic Inquiry|创新与城市间知识溢出:社会、地理和技术的连通性和心理开放性
    css常见动画
    JavaScript基础 | 内置函数知识梳理
  • 原文地址:https://blog.csdn.net/qq_62712350/article/details/126319408