最新Java基础系列课程--Day08-面向对象高级(二)

简介: 最新Java基础系列课程--Day08-面向对象高级

最新Java基础系列课程--Day08-面向对象高级(一)https://developer.aliyun.com/article/1423504


3.2 抽象类的好处

接下来我们用一个案例来说一下抽象类的应用场景和好处。需求如下图所示

分析需求发现,该案例中猫和狗都有名字这个属性,也都有叫这个行为,所以我们可以将共性的内容抽取成一个父类,Animal类,但是由于猫和狗叫的声音不一样,于是我们在Animal类中将叫的行为写成抽象的。代码如下

public abstract class Animal {
    private String name;
    //动物叫的行为:不具体,是抽象的
    public abstract void cry();
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

接着写一个Animal的子类,Dog类。代码如下

public class Dog extends Animal{
    public void cry(){
        System.out.println(getName() + "汪汪汪的叫~~");
    }
}

然后,再写一个Animal的子类,Cat类。代码如下

public class Cat extends Animal{
    public void cry(){
        System.out.println(getName() + "喵喵喵的叫~~");
    }
}

最后,再写一个测试类,Test类。

public class Test2 {
    public static void main(String[] args) {
        // 目标:掌握抽象类的使用场景和好处.
        Animal a = new Dog();
        a.cry();  //这时执行的是Dog类的cry方法
    }
}

再学一招,假设现在系统有需要加一个Pig类,也有叫的行为,这时候也很容易原有功能扩展。只需要让Pig类继承Animal,复写cry方法就行。

public class Pig extends Animal{
    @Override
    public void cry() {
        System.out.println(getName() + "嚯嚯嚯~~~");
    }
}

此时,创建对象时,让Animal接收Pig,就可以执行Pig的cry方法

public class Test2 {
    public static void main(String[] args) {
        // 目标:掌握抽象类的使用场景和好处.
        Animal a = new Pig();
        a.cry();  //这时执行的是Pig类的cry方法
    }
}

综上所述,我们总结一下抽象类的使用场景和好处

1.用抽象类可以把父类中相同的代码,包括方法声明都抽取到父类,这样能更好的支持多态,一提高代码的灵活性。
2.反过来用,我们不知道系统未来具体的业务实现时,我们可以先定义抽象类,将来让子类去实现,以方便系统的扩展。

3.3 模板方法模式

学习完抽象类的语法之后,接下来,我们学习一种利用抽象类实现的一种设计模式。先解释下一什么是设计模式?设计模式是解决某一类问题的最优方案

设计模式在一些源码中经常会出现,还有以后面试的时候偶尔也会被问到,所以在合适的机会,就会给同学们介绍一下设计模式的知识。

那模板方法设计模式解决什么问题呢?模板方法模式主要解决方法中存在重复代码的问题

比如A类和B类都有sing()方法,sing()方法的开头和结尾都是一样的,只是中间一段内容不一样。此时A类和B类的sing()方法中就存在一些相同的代码。

怎么解决上面的重复代码问题呢? 我们可以写一个抽象类C类,在C类中写一个doSing()的抽象方法。再写一个sing()方法,代码如下:

// 模板方法设计模式
public abstract class C {
    // 模板方法
    public final void sing(){
        System.out.println("唱一首你喜欢的歌:");
        doSing();
        System.out.println("唱完了!");
    }
    public abstract void doSing();
}

然后,写一个A类继承C类,复写doSing()方法,代码如下

public class A extends C{
    @Override
    public void doSing() {
        System.out.println("我是一只小小小小鸟,想要飞就能飞的高~~~");
    }
}

接着,再写一个B类继承C类,也复写doSing()方法,代码如下

public class B extends C{
    @Override
    public void doSing() {
        System.out.println("我们一起学猫叫,喵喵喵喵喵喵喵~~");
    }
}

最后,再写一个测试类Test

public class Test {
    public static void main(String[] args) {
        // 目标:搞清楚模板方法设计模式能解决什么问题,以及怎么写。
        B b = new B();
        b.sing();
    }
}

综上所述:模板方法模式解决了多个子类中有相同代码的问题。具体实现步骤如下

第1步:定义一个抽象类,把子类中相同的代码写成一个模板方法。
第2步:把模板方法中不能确定的代码写成抽象方法,并在模板方法中调用。
第3步:子类继承抽象类,只需要父类抽象方法就可以了。

四、接口

同学们,接下来我们学习一个比抽象类抽象得更加彻底的一种特殊结构,叫做接口。在学习接口是什么之前,有一些事情需要给大家交代一下:Java已经发展了20多年了,在发展的过程中不同JDK版本的接口也有一些变化,所以我们在学习接口时,先以老版本为基础,学习完老版本接口的特性之后,再顺带着了解一些新版本接口的特性就可以了。

4.1 认识接口

我们先来认识一下接口?Java提供了一个关键字interface,用这个关键字来定义接口这种特殊结构。格式如下

public interface 接口名{
    //成员变量(常量)
    //成员方法(抽象方法)
}

按照接口的格式,我们定义一个接口看看

public interface A{
    //这里public static final可以加,可以不加。
    public static final String SCHOOL_NAME = "黑马程序员";
    //这里的public abstract可以加,可以不加。
    public abstract void test();
}

写好A接口之后,在写一个测试类,用一下

public class Test{
    public static void main(String[] args){
        //打印A接口中的常量
        System.out.println(A.SCHOOL_NAME);
        //接口是不能创建对象的
        A a = new A();
    }
}

我们发现定义好接口之后,是不能创建对象的。那接口到底什么使用呢?需要我注意下面两点

  • 接口是用来被类实现(implements)的,我们称之为实现类。
  • 一个类是可以实现多个接口的(接口可以理解成干爹),类实现接口必须重写所有接口的全部抽象方法,否则这个类也必须是抽象类

比如,再定义一个B接口,里面有两个方法testb1(),testb2()

public interface B {
    void testb1();
    void testb2();
}

接着,再定义一个C接口,里面有两个方法testc1(), testc2()

public interface C {
    void testc1();
    void testc2();
}

然后,再写一个实现类D,同时实现B接口和C接口,此时就需要复写四个方法,如下代码

// 实现类
public class D implements B, C{
    @Override
    public void testb1() {
    }
    @Override
    public void testb2() {
    }
    @Override
    public void testc1() {
    }
    @Override
    public void testc2() {
    }
}

最后,定义一个测试类Test

public class Test {
    public static void main(String[] args) {
        // 目标:认识接口。
        System.out.println(A.SCHOOL_NAME);
        // A a = new A();
        D d = new D();
    }
}

4.2 接口的好处

同学们,刚刚上面我们学习了什么是接口,以及接口的基本特点。那使用接口到底有什么好处呢?主要有下面的两点

  • 弥补了类单继承的不足,一个类同时可以实现多个接口。
  • 让程序可以面向接口编程,这样程序员可以灵活方便的切换各种业务实现。

我们看一个案例演示,假设有一个Studnet学生类,还有一个Driver司机的接口,还有一个Singer歌手的接口。

现在要写一个A类,想让他既是学生,偶然也是司机能够开车,偶尔也是歌手能够唱歌。那我们代码就可以这样设计,如下:

class Student{
}
interface Driver{
    void drive();
}
interface Singer{
    void sing();
}
//A类是Student的子类,同时也实现了Dirver接口和Singer接口
class A extends Student implements Driver, Singer{
    @Override
    public void drive() {
    }
    @Override
    public void sing() {
    }
}
public class Test {
    public static void main(String[] args) {
        //想唱歌的时候,A类对象就表现为Singer类型
        Singer s = new A();
        s.sing();
        //想开车的时候,A类对象就表现为Driver类型
        Driver d = new A();
        d.drive();
    }
}

综上所述:接口弥补了单继承的不足,同时可以轻松实现在多种业务场景之间的切换。


最新Java基础系列课程--Day08-面向对象高级(三)https://developer.aliyun.com/article/1423506

相关文章
|
2月前
|
存储 Java 测试技术
Java基础 - 面向对象
面向对象编程是Java的核心,包含封装、继承、多态三大特性。封装隐藏实现细节,提升代码可维护性与安全性;继承实现类间IS-A关系,支持代码复用;多态通过继承、重写与向上转型,实现运行时方法动态绑定,提升系统扩展性与灵活性。
|
4月前
|
人工智能 Java 编译器
Java:面向对象
本文介绍了Java编程中的核心概念,包括包的命名规范与自动导入机制、构造方法的特点与使用、`this`和`super`关键字的作用、继承的基本规则、访问权限的设置、封装的意义、多态的实现原理以及`static`关键字的用法。通过详细解析每个知识点,并结合代码示例,帮助读者深入理解Java面向对象编程的核心思想与实践技巧。内容适合初学者及进阶开发者学习参考。
108 0
|
6月前
|
缓存 安全 Java
java面试-基础语法与面向对象
本文介绍了 Java 编程中的几个核心概念。首先,详细区分了方法重载与重写的定义、发生阶段及规则;其次,分析了 `==` 与 `equals` 的区别,强调了基本类型和引用类型的比较方式;接着,对比了 `String`、`StringBuilder` 和 `StringBuffer` 的特性,包括线程安全性和性能差异;最后,讲解了 Java 异常机制,包括自定义异常的实现以及常见非检查异常的类型。这些内容对理解 Java 面向对象编程和实际开发问题解决具有重要意义。
|
9月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
102 1
|
10月前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
87 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
|
12月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
10月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
175 2
|
12月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
97 4
|
12月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
11月前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
79 0

热门文章

最新文章