Java开发零基础篇:day09 面向对象(三)

简介: 面向对象

 多态思想

接口

接口概述

image.gif编辑

我们要完成一个工程,需要一个插座

思考1:去市场买个回来!=> 市场上有公牛、小米... => 小米和公牛认识吗?

什么原因导致公牛和小米的插座我都可以用?

接口是一种约定的规范,是多个抽象方法的集合。仅仅只是定义了应该有哪些功能,本身不实现功 能,至于每个功能具体怎么实现,就交给实现类完成。

接口中的方法是抽象方法,并不提供功能实现,体现了规范和实现相分离的思想,也体现了组件之 间低耦合的思想。

所谓耦合度,表示组件之间的依赖关系。依赖关系越多,耦合性越强,同时表明组件的独立性越 差,在开发中往往提倡降低耦合性,可提高其组件独立性,举一个低耦合的例子。

电脑的显卡分为集成显卡和独立显卡:

集成显卡:显卡和主板焊死在一起,显卡坏了,只能换主板

独立显卡:显卡和主板相分离,显卡插到主板上即可,显卡坏了,只换显卡,不用换主板

接口也体现的是这种低耦合思想,接口仅仅提供方法的定义,却不提供方法的代码实现。那么得专 门提供类并去实现接口,再覆盖接口中的方法,最后实现方法的功能,在多态案例中再说明。

接口定义和多继承性

接口可以认为是一种特殊的类,但是定义类的时候使用class关键字,定义接口使用interface关键字。

public  interface   接口名{
    //抽象方法1();
    //抽象方法2();
    //抽象方法2();
}

image.gif

接口表示具有某些功能的事物,接口名使用名词,有人也习惯以I开头。 接口定义代码:

public interface IWalkable { 
    void walk();
}

image.gif

接口中的方法都是公共的抽象方法,等价于:

public interface IWalkable { 
    public abstract void walk();
}

image.gif

从Java8开始, Java支持在接口中定义有实现的方法, 如:

public interface IWalkable {
    public abstract void walk();//抽象方法
    default void defaultMethod(){
        System.out.println("有默认实现的方法, 属于对象");
    }
    static void defaultMethod(){
        System.out.println("有默认实现的方法, 属于类");
    }
}

image.gif

在java中,接口也可以继承,一个接口可以继承多个接口,也就是说一个接口可以同时继承多个接口, 如两栖动物可以行走也可以拥有。

可行走规范:

public interface IWalkable { 
    void walk();
}

image.gif

可游泳规范:

public interface ISwimable { 
    void swim();
}

image.gif

两栖动物规范,即可以游泳,又可以行走:

public interface IAmphibiable   extends IWalkable,ISwimable{
}

image.gif

此时子接口能继承所有父接口的方法。

接口实现类

(1)因为接口中的方法时抽象的,没有方法体,所以接口是不能创建对象的,此时必须定义一个类去实现接口,并覆盖接口中的方法,这个类称之为实现类,实现类和接口之间的关系称之为实现关系(implements)

public class 类名 implements 接口名{
    //覆盖接口中抽象方法
}

image.gif

实现类实现接口后,必须实现接口中的所有抽象方法,完成功能代码,此时接口和实现类之间的关系:

接口:定义多个抽象方法,仅仅定义有哪些功能,却不提供实现。

实现类:实现接口,实现接口中抽象方法,完成功能具体的实现。

如果实现类没有全部实现接口中的方法,要么报错,要么把实现类设置为抽象类(下图)。

image.gif编辑

定义一个猫类(Cat)实现IWalkable接口,并创建对象调用方法。

public class Cat implements IWalkable{
    public void walk() {
        System.out.println("走猫步...");
    }
}

image.gif

根据方法覆盖原则:子类方法的访问修饰符必须大于等于父类方法的访问修饰符,接口中的方法都是public修饰的,所以实现类中的方法只能使用public修饰

定义一个人类,实现ISwimable,IWalkable接口

public class Person implements ISwimable, IWalkable { 
    @Override
    public void walk() {
        System.out.println("人类步行...");
    }
    @Override
    public void swim() {
        System.out.println("人类游泳...");
    }
}

image.gif

实现类实现了接口,一定具备接口中定义的能力。

(2)实现类可以继承父类,但可以同时实现一个或多个接口,继承在前,实现在后。

定义一个青蛙类(Frog)继承于动物类(Animal),同时实现于会走路(IWalkable),会游泳(ISwimable)的接口,语法如下:

public class Frog extends Animal implements ISwimable,IWalkable{
    public void walk() {
        System.out.println("跳啊跳...");
    }
    public void swim() {
        System.out.println("游啊游..");
    }
}

image.gif

(3)接口是一种引用数据类型,可以用来声明变量,并接收(引用)所有该接口的实现类对象。如果要创 建实现类对象,语法如下:

接口 变量 = new 实现类();

测试类:

public static void main(String[] args) {
    /**
    *   学生找房子,由于条件不足,所以委托中介帮忙找房子,但又不想强依赖于中介
    */
    // 使用接口声明变量的意义在于?
    IRentable rentable = null;
    // 使用rentable可以引用其实现类
    rentable = new Agent("链家");
    /**
    *   rentable 引用实现类更在乎实现类啊,你具不具备我接口约定的能力,而不关心你到底是谁
    */
    Student student = new Student("二狗");
    // student.setRentable(rentable);
    rentable = new Teacher(); student.setRentable(rentable);
    student.findHouse();
}

image.gif

接口总结

(1)接口表示一种规约(规范、标准),它里面定义了一些列抽象方法(功能),它可以被多个类实现。

(2)实现类实现接口,必须实现接口中的所有抽象方法。我们经常说:接口约定了实现类应该具备的能力

(3)面向接口编程。

多态

多态概念

多态是面向对象三大特征之一:封装、继承、多态。

在继承关系,是一种 is A 的关系,也即什么是什么 ,也就说子类是父类的一种特殊情况,有如下代码:

public class Animal{}
public class Dog extends Animal{}   // Dog is a Animal 
public class Cat extends Animal{}   // Cat is a Animal

image.gif

那么我们可以认为狗和猫都是一种特殊的动物,那么可以使用动物类型来表示狗或猫。

Dog d = new Dog();  //创建一只狗对象,赋给子类类型变量
Animal a = ne Cat() //创建一只猫对象,赋给父类类型变量

image.gif

此时对象(a)具有两种类型:

编译时类型:声明对象变量的类型——>Animal

运行时类型:对象的真实类型 ——>Dog

当编译类型和运行类型不一致的时候,此时多态就产生了。

注意:编译类型必须是运行类型的父类或接口。

所谓多态,表示一个对象具有多种形态。

说的具体点就是同一引用类型变量调用同一方法时,由于引用实例不同,方法产生的结果不同。

Animal  a = null;
a = new Dog(); //a此时表示Dog类型的形态
a = new Cat(); //a此时表示Cat类型的形态

image.gif

多态的前提,可以是继承关系(类和类),也可以是实现关系(接口和实现类),在开发中,一般都指 接口和实现类之间的关系。

一言以蔽之:父类引用变量指向于子类对象,调用方法时实际调用的是子类的方法。

我家有一种动物,你猜它的叫声是怎么样的,猜不到,因为这个动物有多种形态。

如果该动物是狗,叫声是:旺旺旺...

如果该动物是猫,叫声是:妙妙妙...

多态操作有两种定义格式和操作语法:

操作继承关系:

父类 变量名 = new 子类(); 
变量名.方法();

image.gif

操作实现关系:

接口 变量名 = new 实现类(); 
变量名.方法();

image.gif

操作继承关系

父类 变量名 = new 实现类(); 
变量名.方法();

image.gif

Animal类:

public class Animal { 
    public void shut() {
        System.out.println("Animal...shout...");
    }
}

image.gif

Cat类:

public class Cat extends Animal{ 
    public void shut() {
        System.out.println("妙妙妙...");
    }
}

image.gif

Dog类:

public class Dog extends Animal{ 
    public void shut() {
        System.out.println("旺旺旺...");
    }
}

image.gif

测试类:

public class AnimalDemo {
    public static void main(String[] args) {
        // 创建Cat对象
        Animal a = new Cat(); a.shout();
        // 创建Dog对象
        a = new Dog(); 
        a.shout();
    }
}

image.gif

控制台输出:

妙妙妙...
旺旺旺...

image.gif

父类引用变量指向于子类对象,调用方法时实际调用的是子类的方法。

操作实现关系

接口 变量名 = new 实现类(); 
变量名.方法();

image.gif

ISwimable 接口:

public interface ISwimable { 
    void swim();
}

image.gif

Fish类:

public class Fish implements ISwimable{ 
    public void swim() {
        System.out.println("游啊游...");
    }
}

image.gif

测试类:

public class FishDemo {
    public static void main(String[] args) {
        // 创建Fish对象
        ISwimable fish = new Fish();
        fish = new Dog();//Dog也是实现了ISwimable接口的
        Fish f = new Fish();
        fish.swim();
    }
}

image.gif

控制台输出:

游啊游...

image.gif

接口引用变量指向实现类对象,调用方法时实际调用的是实现类实现接口的方法。

多态时方法调用问题

把子类对象赋给父类变量,此时调用方法:

Animal a = new Cat(); 
a.shut();

image.gif

那么a对象调用的shut方法,是来自于Animal中还是Cat中?

判断规则如下:

image.gif编辑

先判断shout方法是否在父类Animal类中:

找不到:编译报错

找 到:再看shout方法是否在子类Cat类中

找不到:运行父类方法

找 到:运行子类方法(这个才是真正的多态方法调用)

多态小结

// Dog d = new Dog();
// Cat c = new Cat();
Animal a = new Cat(); 
a.xxx();
a.ooo();
IEmployeeService service = new EmployeeServiceImpl2(); 
service.save();
service.delete();

image.gif

所谓多态,就是一个对象的多种形态,这个对象一般都比较抽象,当通过同一引用类型,由于引用的实例不同,对同一行为产生的结果不同。

多态中的类型转换

类型转换

自动类型转换:把子类对象赋给父类变量(多态)

Animal a = new Dog();
Object  obj = new Dog();    //Object是所有类的根类

image.gif

强制类型转换:把父类类型对象赋给子类类型变量。

子类类型 变量 = (子类类型)父类对象;

image.gif

Animal a = new Dog();
Dog d = (Dog) a;//正确
Cat c = (Cat) a;//错误

image.gif

instanceOf

instanceof 运算符:判断该对象是否是某一个类/接口的实例。

语法格式:
boolean b = 对象A instanceof  类B; //判断 A对象是否是 B类的实例?如果是,返回true

image.gif

代码如下:

Animal a = new Dog(); 
System.out.println(a instanceof Animal); //true
System.out.println(a instanceof Dog);    //true
System.out.println(a instanceof Cat);    //false

image.gif

USB案例

模拟在主板上安装鼠标、键盘等,比较没有规范和有规范的区别。

没有统一规范:

鼠标类:

public class Mouse {
    //鼠标工作的方法
    public void work1() {
        System.out.println("鼠标在移动");
    }
}

image.gif

键盘类:

public class Keyboard {
    //键盘工作的方法
    public void work2() {
        System.out.println("鼠标在移动");
    }
}

image.gif

主板类:

public class MotherBoard {
    //在主板上安装鼠标对象
    public void plugin(Mouse m) { 
        m.work1();  //调用鼠标工作的方法
    }
    //在主板上安装键盘对象
    public void plugin(Keyboard k) { 
        k.work2();  //调用键盘工作的方法
    }
}

image.gif

上述代码是没有统一规范的,我们能发现其中的问题:

不同设备中工作的方法名称是不一致的

每次需要安装新设备,都需要在主板类上新增一个方法

有统一规范:

USB规范接口:

//定义一种规范,用来约束所有的USB设备应该具有的功能
public interface IUSB {
    //USB设备工作的方法
    void swapData();
}

image.gif

在Mouse和Keyboard类遵循于USB规范——工作的方法名称也就相同了。

public class Mouse implements IUSB{
    public void swapData() {
        System.out.println("鼠标在移动");
    }
}
public class Keyboard implements IUSB{
    public void swapData() {
        System.out.println("用键盘打字");
    }
}

image.gif

主板类,在安装方法plugin上也体现出了多态的特征:

public class MotherBoard {
    //IUSB类型可以接受实现类对象 
    public void plugin(IUSB usb) {
        usb.swapData();
    }
}

image.gif

面向接口编程,体现的就是多态,其好处:把实现类对象赋给接口类型变量,屏蔽了不同实现类之间的实现差异,从而可以做到通用编程。

测试类:

public class USBDemo {
    public static void main(String[] args) {
        // 创建主板对象
        MotherBoard board = new MotherBoard();
        // 创建鼠标对象
        Mouse m = new Mouse();
        // 创建键盘对象
        Keyboard k = new Keyboard();
        //在主板上安装鼠标
        board.plugin(m);
        //在主板上安装键盘
        board.plugin(k);
    }
}

image.gif

以上就是Java入门第九天的全部内容了。

资料文档地址:Java开发零基础篇:day09面向对象(三).pdf

相关文章:Java开发零基础篇:day06 面向对象(一)

                 Java开发零基础篇:day08 面向对象(二)

                 Java开发零基础篇:day10 面向对象(四)

目录
相关文章
|
4天前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
8天前
|
前端开发 Oracle Java
【前端学java】java开发的依赖安装与环境配置(1)
【8月更文挑战第8天】java开发的依赖安装与环境配置
26 1
【前端学java】java开发的依赖安装与环境配置(1)
|
1天前
|
数据采集 供应链 JavaScript
分享基于Java开发的Java毕业设计实战项目题目
这篇文章分享了67套基于Java开发的毕业设计实战项目题目,覆盖了互联网、企业管理、电子政务、Java基础项目、ERP系统、校园相关、医疗以及其他细分行业等多个领域,并推荐了使用IDEA、Vue和Springboot的技术栈。
|
1天前
|
分布式计算 Java API
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率。流处理采用声明式编程模型,通过filter、map等操作简化数据集处理,提高代码可读性。Lambda表达式支持轻量级函数定义,配合Predicate、Function等接口,使函数式编程无缝融入Java。此外,Optional类及新日期时间API等增强功能,让开发者能更优雅地处理潜在错误,编写出更健壮的应用程序。
6 1
|
6天前
|
SQL 存储 Java
完整java开发中JDBC连接数据库代码和步骤
该博客文章详细介绍了使用JDBC连接数据库的完整步骤,包括加载JDBC驱动、提供连接URL、创建数据库连接、执行SQL语句、处理结果以及关闭JDBC对象的过程,并提供了相应的示例代码。
|
6天前
|
安全 前端开发 Java
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
在Web安全上下文中,源(Origin)是指一个URL的协议、域名和端口号的组合。这三个部分共同定义了资源的来源,浏览器会根据这些信息来判断两个资源是否属于同一源。例如,https://www.example.com:443和http://www.example.com虽然域名相同,但由于协议和端口号不同,它们被视为不同的源。同源(Same-Origin)是指两个URL的协议、域名和端口号完全相同。只有当这些条件都满足时,浏览器才认为这两个资源来自同一源,从而允许它们之间的交互操作。
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
|
11天前
|
Java 数据安全/隐私保护
09 Java面向对象三大特征(概述)
09 Java面向对象三大特征(概述)
31 4
|
11天前
|
存储 Java 程序员
08 Java面向对象基础(对象与类+实例变量与方法+构造方法+this关键字)
08 Java面向对象基础(对象与类+实例变量与方法+构造方法+this关键字)
33 4
|
23天前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
【7月更文挑战第28天】在 Android 开发中, NDK 让 Java 与 C++ 混合编程成为可能, 从而提升应用性能。**为何选 NDK?** C++ 在执行效率与内存管理上优于 Java, 特别适合高性能需求场景。**环境搭建** 需 Android Studio 和 NDK, 工具如 CMake。**JNI** 构建 Java-C++ 交互, 通过声明 `native` 方法并在 C++ 中实现。**实战** 示例: 使用 C++ 计算斐波那契数列以提高效率。**总结** 混合编程增强性能, 但增加复杂性, 使用前需谨慎评估。
58 4
|
1天前
|
人工智能 网络协议 Java
23.12月中旬 上海寻序人工智能科技-上海嘉定-Java开发实习生-薪资150-230/d 面经
关于上海寻序人工智能科技有限公司Java开发实习生岗位的面试经验分享,涵盖了技术问题如对象存储MinIO、ArrayList扩容、Object类方法、hashCode和equals方法、处理哈希冲突、JVM垃圾回收器、GC算法、网络协议、邮件协议、HTTP请求方法、Linux和Docker命令、Dockerfile制作等。
3 0