(十四)面向对象的三大特征
创始人
2024-05-09 03:38:37
0

目录

前言:

一、面向对象三大特征之一:封装

二、面向对象三大特征之二:继承

三、面向对象三大特征之三:多态


前言:

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

一、面向对象三大特征之一:封装

1.概述:

        封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在java中通过关键字private,protected和public实现封装。什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。

        封装:告诉我们,如何正确设计对象的属性和方法。

        封装的原则:对象代表什么,就得封装对应的数据,并提供数据对应得行为。

        private:修饰的成员只能在当前类中访问。

2.例子:

public class Show{public static void show(String str){System.out.println(str);}}

上面就是对 System.out.println();的封装。

调用的时候 :

public class Use{public static void main(String[] args){Show.show("封装");}}

这样用的时候就不用使:System.out.println("封装");

二、面向对象三大特征之二:继承

1.什么是继承?

        java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起父子关系。

        public class Student extends people{}

        Student称为子类(派生类),people称为父类(基类或超类)。

        父类(super)、子类(this)

        作用:      当子类继承父类后,就可以直接使用父类公共的属性和方法了。

2.继承规范:

        ①子类们相同特征(共性属性,共性方法)放在父类中定义。

        ②子类独有的属性和行为应该定义在子类自己里面。

3.继承的特点:

        ①子类有自己的构造器,不能继承父类的构造器 ②子类是否可以继承父类的私有成员(可以继承父类的私有成员,只是不能直接访问! )

        ③子类是否可以继承父类的静态成员(不是继承,是共享的父类的) ​ ④java只能继承一个父类,不支持多继承,不过支持多层继承。 多层继承: A继承B,B继承C;

        ⑤object :object是祖宗类

4.在子类中给访问成员(成员变量、成员方法)满足:就近原则(局域对象<子类对象<父类对象)

        ①先子类局部范围找。

        ②然后子类成员范围找。

        ③然后父类成员范围找,如果父类范围还没有找到则报错。

5.如果子父类中,出现了重名的成员,会优先使用子类的,此时如果一定要在子类中使用父类的怎么办?

        ①可以通过super关键字,指定访问父类的成员。

                格式:super.父类成员变量/父类成员方法

        ②可以通过this关键字,指定访问子类的成员。

                格式:this.子类成员变量/子类成员方法

6.继承后:方法重写

        在继承体系中,子类出现了和父类中一摸一样的方法声明,我们就称子类这个方法是重写的方法。

7.方法重写的应用场景

        ①当子类需要父类的功能,但父类的该功能不完全满足自己的需求时。

        ②子类可以重写父类中的方法。

8.@Override重写注解:

        放在重写后的方法上,作为重写是否正确的校验注解。

作用:

        1.这个方法必须是正确重写的;

        2.提高代码的可读性,代码优雅。

注意:

        ①重写方法的名词称、形参列表必须与被重写方法的名称和参数列表一致。

        ②私有方法不能被重写。

        ③子类重写父类方法时,访问权限必须大于或者等于父类。

        ④子类不能重写父类的静态方法,如果重写会报错。

9.方法重写案例:

 旧手机的功能只能是基本的打电话,发信息;

新手机的功能需要能够在基本的打电话下支持视频通话。基本的发信息下支持发送语音和图片。

main类:

public class extends_Test {public static void main(String[] args) {//方法重写newphone nw = new newphone();nw.call();nw.sending();}
}
新手机类(子类):
​​​​​​​/*
新手机:子类*/
class newphone extends phone{//重写的方法@Override//1.这个方法必须是正确重写的;2.提高代码的可读性,代码优雅。public void call(){super.call();//先用父类的基本功能System.out.println("开始视频通话");}//重写的方法@Overridepublic void sending(){super.sending();//先用父类的基本功能System.out.println("发送有趣的图片~~");}
}
旧手机类(父类):
/*
旧手机:父类*/
class phone{public void call(){System.out.println("打电话");}public void sending(){System.out.println("发短信");}
}

10.继承后:子类继承父类后构造器的特点:

        子类所有构造器都会先访问父类构造器,再调用自己的构造器,初始化父类的数据。

为什么?

        ①子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。

        ②子类初始化之前,一定要调用父类构造器先完成父类数据空间的初始化。

怎么调用父类构造器?

        子类构造器的第一行语句默认都是:super(),不写也存在。

11.继承后:子类构造器访问父类有参构造器?

super调用父类有参构造器的作用:

        初始化继承自父类的数据;

 如果父类中没有无参数构造器,只有有参构造器,会出现什么现象呢?

         会报错,因为子类默认是调用父类无参构造器的。

如何解决?

        子类构造器中可以书写super(...),手动调用父类的有参数构造器。

12.代码演示:

猫类(子类):

public class cat extends dog {public cat(){System.out.println("子类cat无参数构造器被执行~~");}public cat(String name){System.out.println("子类cat有参数构造器被执行~~");}
}
狗类(父类):

public class dog {public dog(){System.out.println("父类dog无参数构造器被执行~~");}
}
main类:

public class test1 {public static void main(String[] args) {//继承后子类构造器的特点cat c1 = new cat();System.out.println(c1);System.out.println("----------");cat c2 = new cat("金毛");System.out.println(c2);}
}
 

13.this和super小结

        this:代表本类对象的引用;
        super:代表父类存储空间的标识。

  • this()和super()必须要在第一行,所以一个构造器中不能共存this()和super();

  • this :访问子类当前对象的成员

  • super :在子类方法中指定访问父类的成员

  • this(...) :访问本类兄弟构造器

  • super(...) : 在本类构造器中指定访问父类的构造器

14.代码演示:

动物类(父类):

public abstract class Animal {public String name = "动物名";
​public void eat() {System.out.println("动物要吃东西!");}
​public static String location = "长隆动物园";
​public abstract void run();
}

老虎类(子类):

public class Tiger extends Animal {public static boolean location;String name = "老虎名";
​public void showName(){String name = "局部名";System.out.println(name);System.out.println(this.name);System.out.println(super.name);super.eat();this.eat();}@Override // 1、重写校验注解,加上之后,这个方法必须是正确重写的,这样更安全  2、提高代码的可读性/**1、重写的名字和形参列表必须与被重写的方法一样* 2、私有方法不能被重写* 3、子类重写父类方法时,访问权限必须大于或者等于父类( 访问权限:privase < 不写 < protected < public)* 4、静态方法不能被子类重写*/public void eat(){super.eat();//方法重写,重写父类System.out.println("老虎在吃东西");}
​@Overridepublic void run() {}
}

实现类:

//extends :子类继承父类  让一个类与另一个类建立父子关系,用于提高代码复用性(子类extends 父类)
//父类(super)、子类(this)
public class extends_Demo4 {/**  继承的特点:* 1、子类有自己的构造器,不能继承父类的构造器* 2、子类是否可以继承父类的私有成员(可以继承父类的私有成员,只是不能直接访问! )* 3、子类是否可以继承父类的静态成员(不是继承,是共享的父类的)* 4、java只能继承一个父类,不支持多继承,不过支持多层继承。  多层继承: A继承B,B继承C;* 5、object :object是祖宗类* 在子类中给访问成员(成员变量、成员方法)满足:就近原则(局域对象<子类对象<父类对象)*///子类所有构造器都会先访问父类构造器,再调用自己的构造器,初始化父类的数据
​/*** this()和super()必须要在第一行,所以一个构造器中不能共存this()和super();* this :访问子类当前对象的成员* super :在子类方法中指定访问父类的成员* this(...) :访问本类兄弟构造器* super(...) : 在本类构造器中指定访问父类的构造器*/public static void main(String[] args) {Tiger t = new Tiger();t.eat();System.out.println(Tiger.location);t.showName();
​}
}

 

三、面向对象三大特征之三:多态

1.概述:

        同类型的对象执行同一个行为,会表现出不同的行为特征。

2.多态的常见形式:

        父类类型 对象名称 = new 子类构造器;

        接口 对象名称 = new 实现类构造器;

3.代码演示:

动物类:

public abstract class Animal {public String name = "动物名";
​public void eat() {System.out.println("动物要吃东西!");}
​public static String location = "长隆动物园";
​public abstract void run();
}

实现类:

public class polymorphic_Demo {public static void main(String[] args) {Animal a = new Animal() {//父类类型 对象名称 = new 子类构造器;@Overridepublic void run() {System.out.println("🐕跑得很快~~");}};a.run();//编译看左边,运行看右边}

4.多态成员访问特点:

  • 方法调用:编译看左边,运行看右边

  • 变量调用:编译看左边,运行看左边(多态侧重行为多态)

5.多态的前提:

        ①有继承/实现关系;

        ②有父类引用指向子类对象;

        ③有方法重写;

6.多态的优势:

        ①在多态的形式下,右边对象可以实现解耦合,便于扩展和维护;

        ②定义方法的时候,使父类型作为参数,该方法可以接收这父类的一切子类对象,体现出多态的扩展性与便利;

        ③多态下不能访问子类的独有功能;

7.多态下引用数据类型的类型转换

  • 自动类型转换(从子到父):子类对象赋值给父类类型的变量指向;

  • 强制类型转换(从父到子):子类 对象变量 = (子类)父类类型的变量;

  • 作用:解决多态下的劣势,实现调用子类独有的功能。

  • 有继承或实现关系编译阶段可以强制转换,但如果转型后的类型和对象的真实类型不是同一种类型,那么在转换的时候就会出现异常:ClassCastException

  •  

  • Java建议强制转换前使用instanceof判断当前对象的真实类型,再进行强制转换;

  • 变量名 instanceof 真实类型:用于判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true;

  •  

9.案例:

需求:

        ①使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备。

        ②鼠标:被安装时可以完成接入、调用点击功能、拔出功能。

        ③键盘:被安装时可以完成接入、调用点击功能、拔出功能。

分析:

        ①定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。

        ②提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。

        ③创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。

USB接口规范类:

/*** USB接口 == 规范*/
public interface USB {//接入、拔出void connect();void unconnect();
}

键盘实现类:

/*** 实现类*/
public class keyBoard implements USB{private String name;
​public keyBoard(String name) {this.name = name;}@Overridepublic void connect() {System.out.println(name+"成功连接电脑");}
​@Overridepublic void unconnect() {System.out.println(name+"成功拔出电脑");}
​/*** 独有功能*/public void keyDown(){System.out.println(name+"敲击了:来了,老弟~~");}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
}

鼠标实现类:

   /*** 实现类*/
public class Mouse implements USB {private String name;public Mouse(String name) {this.name = name;}@Overridepublic void connect() {System.out.println(name + "成功连接电脑");}
​@Overridepublic void unconnect() {System.out.println(name + "成功拔出电脑");}/*** 独有功能*/public void duClick() {System.out.println(name + "双击点亮:小红心~~");}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
}

电脑实现类:

public class computer {private String name;
​public computer(String name) {this.name = name;}public void start(){System.out.println(name+"电脑开机了~~");}
​/*** 提供安装USB设备的入口*/public void installUSB(USB usb){//多态:usb == 可能是鼠标,也可以是键盘usb.connect();//独有功能:先判断再强转if (usb instanceof keyBoard) {keyBoard k = (keyBoard) usb;k.keyDown();}else if(usb instanceof Mouse){Mouse m = (Mouse) usb;m.duClick();}usb.unconnect();}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
}

实现main类:

/*** 目标:USB设备模拟* 1、定义USB接口:插入和拔出* 2、定义两个USB的实现类 :鼠标和键盘* 3、创建一个电脑对象,创建USB设备对象,安装启动*/
public class Test {public static void main(String[] args) {//1.创建电脑对象computer c = new computer("外星人");c.start();//2.创建鼠标和键盘对象USB u = new keyBoard("双飞燕");c.installUSB(u);USB u1 = new Mouse("逻辑");c.installUSB(u1);
​}
}

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...