Java 面向对象(七)

简介: 学习内容: 掌握对象多态性的作用。 了解instanceof关键字。 掌握常见的设计模式。

学习内容:


掌握对象多态性的作用。

了解instanceof关键字。

掌握常见的设计模式。


目录


1、对象的多态性

2、instanceof关键字

3、抽象类与接口的应用

(1)为抽象类与接口实例化

(2)抽象类的实际应用——模板设计

(3)接口的实际应用——制定标准

(4)设计模式 ——工厂设计

(5)设计模式 ——代理设计

(6)设计模式 ---- 适配器设计

(7)抽象类与接口之间的关系


1、对象的多态性

多态性在面向对象中是一个最重要的概念,在Java中面向对象主要有以下两种主要体现:

(1)方法的重载与覆写。

(2)对象的多态性。

对象的多态性主要分为以下两种类型:

(1)向上转型:子类对象—>父类对象。

(2)向下转型:父类对象一>子类对象。

对于向上转型,程序会自动完成,而对于向下转型时,必须明确地指明要转型的子类类型。


🍆对象转型的格式:


对象向上转型:父类 父类对象=子类实例;
对象向下转型:子类 子类对象=(子类)父类实例;


🍆范例:


class A{                               // 定义类A
       public void fun1(){              // 定义fun1()方法
              System.out.println("A --> public void fun1(){}") ;
       }
       public void fun2(){
              this.fun1() ;           // 调用fun1()方法
       }
}
class B extends A{
       public void fun1(){              // 此方法被子类覆写了
              System.out.println("B --> public void fun1(){}") ;
       }
       public void fun3(){
              System.out.println("B --> public void fun3(){}") ;
       }
}
public class PolDemo02{
       public static void main(String asrgs[]){
              A a = new B() ;                    // 向上转型关系
              B b = (B)a ;           // 发生了向下转型关系
              b.fun1() ;
              b.fun2() ;
              b.fun3() ;
       }
}


🍆运行结果:

B --> public void fun1( ) { }
B --> public void fun1( ) { }
B --> public void fun3( ) { }


说明:如果要想调用子类自己的方法,则一定只能用子类声明对象,另外,在子类中调用了父类中的fun2()方法,fun2()方法要调用fun1()方法,但此时fun1()方法己经被子类所覆写,所以,此时调用的方法是被子类覆写过的方法。在进行对象的向下转型前,必须首先发生对象向上转型,否则将出现对象转换异常


2、instanceof关键字

在Java中可以使用instanceof关键字判断一个对象到底是哪个类的实例。


🍆格式如下:


对象 instanceof 类 —>返回boolean类型
lean result = obj instanceof Class


🍆用法:


声明一个 class 类的对象,判断 obj 是否为 class 类的实例对象

声明一个 class 接口实现类的对象 obj,判断 obj 是否为 class 接口实现类的实例对象

obj 是 class 类的直接或间接子类


3、抽象类与接口的应用

(1)为抽象类与接口实例化

在Java中可以通过对象的多态性为抽象类和接口实例化,这样在使用抽象类和接口时即可调用子类中所覆写过的方法


🍆范例1:通过子类为抽象类实例化


abstract class A{ // 定义抽象类A
    public abstract void print() ;  // 定义抽象方法print()
}
class B extends A { // 定义子类,继承抽象类
    public void print(){  // 覆写抽象方法
        System.out.println("Hello World!!!") ;
    }
}
public class Demo1{
    public static void main(String[] args){
        A a = new B() ;  // 通过子类为抽象类实例化
        a.print() ;
    }
}


🍆范例2:通过子类为接口实例化


interface A{  // 定义接口A
    void print() ;  // 定义抽象方法print()
}
class B implements A {  // 定义子类,实现接口
    public void print(){  // 覆写抽象方法
        System.out.println("Hello World!!!") ;
    }
}
public class Demo2{
    public static void main(String[] args){
        A a = new B() ;  // 通过子类为接口实例化
        a.print() ;
    }
}


🍆运行结果:

Hello World!!!

(2)抽象类的实际应用——模板设计

现有以下一种场景:假如人分为学生和工人,两者都可以发言,发言的内容由学生和工人自己决定,从程序上来讲,学生和工人可以看作继承了“人类”的子类,此时就可以使用抽象类来实现这种场景。


🍆范例:


abstract class Person {   //定义抽象类Person
    private String name;
    private int age;
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return this.name;
    }
    public int getAge() {
        return this.age;
    }
    public void say() {     //发言功能
        System.out.println(this.getContent());  //发言内容由子类决定
    }
    public abstract String getContent();  //定义抽象方法,由子类覆写,决定发言内容
}
class Student extends Person {  //定义Student类继承Person类
    private String school;
    public String getSchool(){
        return this.school;
    }
    public Student(String name,int age,String school) {
        super(name,age);
        this.school = school;
    }
    public String getContent() {   //覆写Person类方法,决定发言内容
        return "学生的发言内容 --> 姓名:" + super.getName() + ", 年龄:" + super.getAge() + ", 学校:" + this.getSchool();
    }
}
class Worker extends Person {  //定义Worker类继承Person类
    private float salary;
    public float getSalary(){
        return this.salary;
    }
    public Worker(String name,int age,float salary) {
        super(name,age);
        this.salary = salary;
    }
    public String getContent() {  //覆写Person类方法,决定发言内容
        return "工人的发言内容 --> 姓名:" + super.getName() + ", 年龄:" + super.getAge() + ", 薪水:" + this.getSalary();
    }
}
public class Demo {
    public static void main(String[] args) {
        Person per1 = new Student("李华",20,"xx学校");  //由子类实例父类对象,即可调用子类所覆写过的方法
        Person per2 = new Worker("张三",30,3000.0f);  //由子类实例父类对象,即可调用子类所覆写过的方法
        per1.say();    //学生发言的内容
        per2.say();    //工人发言的内容
    }
}


🍆运行结果:

学生的发言内容 --> 姓名:李华,年龄:20,学校:xx学校
工人的发言内容 --> 姓名:张三,年龄:30,薪水:3000.0

在Person类中就相当于定义了一个模板,在主方法中调用时,调用的就是普通方法,而子类只需要实现父类中的抽象方法,就可以取得一个具体的信息。每个子类实现模板中的抽象方法就能够产生不同的模板内容 。


(3)接口的实际应用——制定标准

现实生活中,U盘和打印机等设备均可以通过USB接口在计算机上使用,因为他们都符合 USB接口 标准。以下实例通过接口模拟制定USB接口标准,实现此场景。


🍆范例:制定USB接口


interface USB {   //定义USB接口
    void start();
    void stop();
}
class Computer {   //计算机
    public static void plugin(USB usb) {  //只要是符合USB接口的设备都可以接入
        usb.start();               //让USB设备开始工作
        System.out.println("-----------USB设备工作中----------");
        usb.stop();                //让USB设备停止工作
    }
}
class UDisk implements USB {    //U盘
    public void start() {   //覆写start()方法
        System.out.println("U盘已接入");
    }
    public void stop() {   //覆写stop()方法
        System.out.println("安全移除设备");
    }
}
class Print implements USB {  //打印机
    public void start() {  //覆写start()方法
        System.out.println("打印机已接入");
    }
    public void stop() {  //覆写stop()方法
        System.out.println("打印机停止工作");
    }
}
public class Demo {
    public static void main(String[] args) {
        Computer.plugin(new UDisk());  //接入U盘
        System.out.println(); //换行
        Computer.plugin(new Print());  //接入打印机
    }
}


🍆运行结果:


U盘已接入
-----------USB设备工作中----------
安全移除设备
打印机已接入
-----------USB设备工作中----------
打印机停止工作
接口就是一个标准,计算机认的只是接口,而对于具体的设备,计算机本身并不关心.

(4)设计模式 ——工厂设计

工厂设计是Java开发中使用得最多的一种设计模式,那么什么叫工厂设计?


🍆范例:


interface Fruit{
    void eat();
}
class Apple implements Fruit{
    public void eat(){
        System.out.println("吃苹果");
    }
}
class Orange implements Fruit{
    public void eat(){
        System.out.println("吃橘子");
    }
}
public class InterfaceCaseDemo02 {
    public static void main(String[] args) {
        Fruit f1 = new Apple();
        f1.eat();
        Fruit f2 = new Orange();
        f2.eat();
    }
}


🍆运行结果:


吃苹果
吃橘子


在主方法中,子类为接口实例化后,调用被子类覆写过的方法,从程序中可以发现,每更换一个子类,都需要进行实例化,那么此时就可以在接口和子类之间加入一个过渡端,通过此过渡端进行实例化过程,返回接口实例


interface Fruit{
    void eat();
}
class Apple implements Fruit{
    public void eat(){
        System.out.println("==吃苹果==");
    }
}
class Orange implements Fruit{
    public void eat(){
        System.out.println("==吃橘子==");
    }
}
class Factory {  //定义工厂类
    public static Fruit getInstance(String className) {
        Fruit f = null;
        if("apple".equals(className)){  //判断是哪个子类
            f = new Apple();            //进行实例化
        }
        if("orange".equals(className)){
            f = new Orange();
        }
        return f;   //返回接口实例
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Fruit f1 = null;
        f1 = Factory.getInstance("apple"); //通过工厂取得实例
        f1.eat();  //调用方法
    }
}


🍆运行结果:


吃苹果


(5)设计模式 ——代理设计

代理设计是指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其它相关业务的处理,就好像生活中,用户通过网络代理服务器进行上网,由代理服务器完成用户权限和访问限制等相关的控制操作,而真实主题的服务器负责用户上网操作过程


🍆范例:


interface Network{   //定义上网接口
    void browse();   //上网操作抽象方法
}
class Real implements Network{  //真实的上网操作
    public void browse(){
        System.out.println("上网浏览信息");
    }
}
class Proxy implements Network{  //代理上网
    private Network network;
    public Proxy(Network network){
        this.network = network;
    }
    public void check(){   //上网相关的控制操作
        System.out.println("检查用户是否合法");
    }
    public void browse(){
        this.check();    //执行代理上网的相关控制操作
        this.network.browse();  //调用真实的上网操作
    }
}
public class Demo {
    public static void main(String[] args) {
        Network net = new Proxy(new Real());  //实例化代理,传入真实的上网操作
        net.browse();
    }
}


🍆运行结果:


检查用户是否合法
上网浏览信息

(6)设计模式 ---- 适配器设计

在Java程序中,如果一个类要实现一个接口,则必须要覆写此接口中的全部抽象方法,那么如果此时一个接口中定义的抽象方法过多,但是子类又用不到这么多的抽象方法,那么就比较麻烦。所以此时可以定义一个抽象类作为过渡,即一个接口首先被一个抽象类先实现(此抽象类通常称为适配器类),并在此抽象类中实现若干方法(方法体为空),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法 。


🍆范例:


interface Window{  // 定义Window接口,表示窗口操作
    public void open() ;  // 打开
    public void close() ; // 关闭
    public void activated() ; // 窗口活动
    public void iconified() ; // 窗口最小化
    public void deiconified();// 窗口恢复大小
}
abstract class WindowAdapter implements Window{
    public void open(){} ;  // 打开
    public void close(){} ; // 关闭
    public void activated(){} ; // 窗口活动
    public void iconified(){} ; // 窗口最小化
    public void deiconified(){};// 窗口恢复大小
};
class WindowImpl extends WindowAdapter{
    public void open(){
        System.out.println("窗口打开。") ;
    }
    public void close(){
        System.out.println("窗口关闭。") ;
    }
};
public class Demo{
    public static void main(String args[]){
        Window win = new WindowImpl() ;
        win.open() ;
        win.close() ;
    }
}


🍆运行结果:

窗口打开。
窗口关闭。


以上代码中因为采用了适配器这个中间环节,所以子类就不用必须实现接凵中的全部方法,而是有选择地实现所需要的方法。


(7)抽象类与接口之间的关系

抽象类与接口在系统设计上都是用得最多的


🍆两者的主要区别:

image.png



目录
相关文章
|
1月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
30 1
|
2月前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
29 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
|
2月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
50 2
|
4月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
4月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
45 4
|
4月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
3月前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
36 0
|
5月前
|
Java 数据处理 开发者
【Java基础面试十二】、说一说你对面向对象的理解
这篇文章阐述了面向对象是一种以类和对象为基础,通过封装、继承和多态等概念来模拟现实世界中的事物及其相互关系的程序设计方法,它强调以事物为中心进行思考和系统构造,与结构化程序设计相比,更符合人类的自然思维方式。
【Java基础面试十二】、说一说你对面向对象的理解
|
5月前
|
Java
【Java基础面试十三】、面向对象的三大特征是什么?
这篇文章介绍了面向对象程序设计的三大基本特征:封装、继承和多态,其中封装隐藏对象实现细节,继承实现软件复用,多态允许子类对象表现出不同的行为特征。
【Java基础面试十三】、面向对象的三大特征是什么?
|
4月前
|
安全 Java Go
面向对象程序设计语言:Java
Java语言语法和C语言和C++语言很接近,很容易学习和使用,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的特性,Java语言不使用指针,而是引用,并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧
85 2