codecamp

第6篇-JAVA面向对象Ⅱ

  • 每篇一句 :敢于向黑暗宣战的人,心中必定充满光明
  • 初学心得 : 面向对象 春暖花开
  • (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-05| JAVA面向对象 Ⅱ]

1.JAVA面向对象三大特征

1.封装(Encapsulation); 2.继承(Inheritance); 3.多态(Polymorphism)

2.面向对象 之 封装

什么是封装?
封装就是隐藏实现细节,仅对外提供访问接口
封装的类型有:属性封装、方法封装、类封装、组件封装、模块化封装、系统级封装....

封装的两个含义
1.把对象的状态和行为看成一个统一的整体,将二者存放在一个独立的模块中(类)
2."信息隐藏",把不需要让外界知道的信息隐藏起来,尽可能隐藏对象功能实现细节,字段

封装机制在程序中的体现
把描述对象的状态用字段表示,描述对象的行为用方法表示,把字段和方法定义在一个类中,并保证外界不能任意更改其内部的字段值,也不允许任意调动其内部的功能方法
封装在程序中的一种体现:通常将类中的成员变量私有化(private),通过对外提供方法(set方法,get方法),可对该变量(xxx)进行访问

属性的封装
当某些属性或方法被修饰为私有的,那么这些属性或方法就不能被类的外面直接访问
(1).把属性定义为私有的(只能在本类中访问)
(2).为属性提供getter取值方法、setter设置方法

封装的优点
● 1. 良好的封装能够减少耦合
● 2. 类内部的结构可以自由修改
● 3. 可以对成员变量进行更精确的控制
● 4.模块化、信息隐藏、实现细节、代码重用、插件化易于调试、具有安全性

实现JAVA封装步骤
1.修改属性的可见性来限制对属性的访问(一般为private修饰符)

/**
*定义一个Person类
*隐藏信息
**/
public class Person {
private String name; //定义私有的属性
private int age; //定义私有属性
}
这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏


2.对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问

/**
*定义一个Person类,隐藏信息并提供访问
**/
public class Person{
private String name; //定义私有的属性
private int age; //定义私有的属性
//取得getAge方法
public int getAge(){
return age;
}
//取得getName方法
public String getName(){
return name;
}
//设置setAge方法
public void setAge(int age){
this.age = age;
}
//设置setName方法
public void setName(String name){
this.name = name;
}
}

3.面向对象 之 继承

什么是继承(extends)?
子类自动共享父类数据和方法的机制,这是类之间的关系就是叫做继承
继承概念:被继承的类称为父类(超类),继承父类的类称为子类(派生类)
继承是指一个对象直接使用另一个对象的属性和方法,通过继承可以实现代码重用

super关键字可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
使用super调用父类中的属性,调用父类的方法,调用父类中的构造方法
super 表示父类对象的默认引用
super如果子类要调用父类被覆盖的实例方法,可用super作为调用者调用父类被覆盖的实例方法
使用super调用父类方法,使用super调用父类的构造方法

this 与super 区别
| NO. | 区别 | this | super |
| :-------- | --------:| :------: | :------: |
| 1. | 使用 | 调用本类中的字段或方法 | 从子类调用父类中的字段或方法 |
| 2. | 构造 | 可以调用本类构造方法,且有一个构造方法要作为出口 | 从子类调用父类的构造方法,不管子类如何安排最终一定会去调用,默认调用的是父类中的无参构造方法 |
| 3. | 要求 | 调用自身构造方法时放在构造方法首行 | 调用父类构造方法时放在子类构造方法首行 |
| 4. | 特殊 | 表示当前对象 | 表示父类对象 |


方法的覆写:方法覆写又称为方法覆盖
产生原因:当父类中某个方法不适合于子类时,子类出现父类一模一样的方法
调用被覆盖的父类方法:使用super.方法名(实参);
方法覆写时应遵循的原则(一同,两小,一大)
(一同):方法签名必须相同;
(两小):子类方法的返回值类型比父类方法的返回值类型更小或相等

子类方法声明抛出的异常应比父类方法申明抛出的异常更小或相等
(一大):子类方法的访问权限应比父类方法更大或相等

(Overload 重载) 与 (Override 覆写) 区别
| NO. | 区别 | (Overload)重载 | (Override)覆写 |
| :-------- | --------:| :------: | :------: |
| 1. | 判断规则 | 两同一不同 | 一同两小一大 |
| 2. | 权限 | 没有权限要求 | 被覆写的方法不能拥有比父类更严格的权限 |
| 3. | 范围 | 发生在一个类中 | 发生在继承关系中 |
| 4. | 术语 | Overload | Override |
| 5. | 多态 | 编译时多态 | 运行时多态 |

子类对象实例化过程
在继承操作中,对于子类对象的实例化:
子类对象在实例化之前必须首先调用父类中的构造方法之后再调用自身的构造方法
在子类进行实例化操作时,首先会让其父类进行实例化操作(调用父类的构造方法),之后子类再自己进行实例化操作

子类访问父类
子类不能直接访问父类的私有成员,但是子类可以调用父类中的非私有方法来间接访问父类的私有成员

在 JAVA中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类
类的继承格式:在 JAVA中通过 extends 关键字可以申明一个类是从另外一个类继承而来的

/**
*定义一个类
**/
class 父类 {
}
/**
*定义一个类继承父类
**/
class 子类 extends 父类 {
}


为什么需要继承? :接下来笔者通过代码实例来说明这个需求
开发汽车类,其中汽车分别为奥迪A6以及奔驰R350,要求如下:
● 奥迪A6:属性(id,车名,颜色,速度),方法(汽车基本信息,汽车动力信息)
● 奔驰R350:属性(id,车名,颜色,速度),方法(汽车基本信息,汽车动力信息)

奥迪A6 汽车类
public class AudiA6 {
private int id; //定义私有汽车id号属性
private String carname; //定义私有车名属性
private String colors; //定义私有颜色属性
private double speed; //定义私有速度属性
//定义带参构方法
public AudiA6(int id,String carname,String colors,double speed){
this.id = id;
this.carname = carname;
this.colors = colors;
this.speed = speed;
}
//取得getId方法
public int getId(){
return id;
}
//取得getCarname方法
public String getCarname(){
return carname;
}
//取得getColors方法
public String getColors(){
return colors;
}
//取得getSpeed方法
public String getSpeed(){
return speed;
}
//设置setId方法
public void setId(int Id){
this.id = id;
}
//设置setCarname方法
public void setCarname(String carname){
this.carname = carname;
}
//设置setColors方法
public void setColors(String colors){
this.colors = colors;
}
//设置setSpeed方法
public void setSpeed(double speed){
this.speed = speed;
}
//定义汽车基本信息方法
public void carinformation(){
System.out.println("汽车基本信息:" +id+carname+colors); //输出汽车id,车名,颜色
}
//定义汽车动力信息方法
public void information(){
System.out.println("汽车动力信息"+ speed); //输出速度
}
}


奔驰R350 汽车类
public class MercedesBenzR350 {
private int id; //定义私有汽车id号属性
private String carname; //定义私有车名属性
private String colors; //定义私有颜色属性
private double speed; //定义私有速度属性
//定义带参构方法
public MercedesBenzR350 (int id,String carname,String colors,double speed){
this.id = id;
this.carname = carname;
this.colors = colors;
this.speed = speed;
}
//取得getId方法
public int getId(){
return id;
}
//取得getCarname方法
public String getCarname(){
return carname;
}
//取得getColors方法
public String getColors(){
return colors;
}
//取得getSpeed方法
public String getSpeed(){
return speed;
}
//设置setId方法
public void setId(int Id){
this.id = id;
}
//设置setCarname方法
public void setCarname(String carname){
this.carname = carname;
}
//设置setColors方法
public void setColors(String colors){
this.colors = colors;
}
//设置setSpeed方法
public void setSpeed(double speed){
this.speed = speed;
}
//定义汽车基本信息方法
public void carinformation(){
System.out.println("汽车基本信息:" +id+carname+colors); //输出汽车id,车名,颜色
}
//定义汽车动力信息方法
public void information(){
System.out.println("汽车动力信息"+ speed); //输出速度
}
}

<font color="red"&从这两段代码我们可以看出来,存在太多重复代码,导致后果就是代码量大且非常多,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错)</font&

所以要从根本上解决这两段代码的问题,我们就需要继承,将两段代码中相同的部分提取出来组成 一个父类

公共的汽车父类:
public class Cars {
private int id; //定义私有汽车id号属性
private String carname; //定义私有车名属性
private String colors; //定义私有颜色属性
private double speed; //定义私有速度属性
//定义带参构方法
public Cars (int id,String carname,String colors,double speed){
this.id = id;
this.carname = carname;
this.colors = colors;
this.speed = speed;
}
//取得getId方法
public int getId(){
return id;
}
//取得getCarname方法
public String getCarname(){
return carname;
}
//取得getColors方法
public String getColors(){
return colors;
}
//取得getSpeed方法
public String getSpeed(){
return speed;
}
//设置setId方法
public void setId(int Id){
this.id = id;
}
//设置setCarname方法
public void setCarname(String carname){
this.carname = carname;
}
//设置setColors方法
public void setColors(String colors){
this.colors = colors;
}
//设置setSpeed方法
public void setSpeed(double speed){
this.speed = speed;
}
//定义汽车基本信息方法
public void carinformation(){
System.out.println("汽车基本信息:" +id+carname+colors); //输出汽车id,车名,颜色
}
//定义汽车动力信息方法
public void information(){
System.out.println("汽车动力信息"+ speed); //输出速度
}
}

<font color="red"&这个Cars类就可以作为一个父类,然后奥迪A6汽车类和奔驰R350汽车类继承Cars公共汽车类之后,就具有父类当中的属性和方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性(复用性主要是可以多次使用,不用再多次写同样的代码)</font&

继承之后的代码

奥迪A6汽车类 继承Cars公共类:
public class AudiA6 extends Cars {
//带参构造方法
public AudiA6(int id,String carname,String colors,double speed) {
super(id, carname, colors, speed);
}
//定义汽车基本信息方法
public void carinformation(){
super.carinformation(); //super调用父类的方法
}
//定义汽车动力信息方法
public void information(){
super.carinformation(); //super调用父类的方法
}
}


奔驰R350汽车类 继承Cars公共类:
public class MercedesBenzR350 extends Cars {
public MercedesBenzR350(int id,String carname,String colors,double speed) {
super(id, carname, colors, speed);
}
//定义汽车基本信息方法
public void carinformation(){
super.carinformation(); //super调用父类的方法
}
//定义汽车动力信息方法
public void information(){
super.carinformation(); //super调用父类的方法
}
}


继承的特性
● 子类拥有父类非private的属性,方法
● 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
● 子类可以用自己的方式实现父类的方法
● Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类
多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类
这是java继承区别于C++继承的一个特性
● 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)

4.面向对象 之 多态

什么是多态?: 多态性指同一个实体同时具有多种形式
多态是同一个行为具有多个不同表现形式或形态的能力,多态性是对象多种表现形式的体现
译时的类型由声明该变量时使用的类型决定
运行时的类型由实际赋给变量的对象决定,如果编译时类型和运行时类型不同,就出现多态性

生活中多态的例子
比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫、小狗、等等
那么我到宠物店说"请给我一只宠物",服务员给我小猫、小狗或者蜥蜴都可以,我们就说"宠物"这个对象就具备多态性

多态的实现方式
1.方法的重载(同一个类里面,返回值相同,方法名相同,参数的个数不同),重写(发生在子类与父类关系中)
2.对象的多态性:是从继承关系中的多个类而来,引用变量类型转换
向上转型:将子类实例化转为父类实例格式:
向上转型(子类→父类):(自动完成) 父类名称 父类对象 = 子类实例 ;

向下转型(父类→子类):(强制完成) 子类名称 子类对象 = (子类名称)父类实例 ;
3.接口
● 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型
● JAVA中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现
4.抽象类和抽象方法

多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化,只修改方法的实现,不必修改方法的声明,继承是多态产生的前提条件

多态的分类:编译时多态:方法重载,运行时多态:方法覆写

多态的优点
● 1. 消除类型之间的耦合关系
● 2. 可替换性
● 3. 可扩充性
● 4. 接口性
● 5. 灵活性
● 6. 简化性

初学(面向对象三大特征) Ⅱ 难点: ★★★★★★

希望每一篇文章都能够对读者们提供帮助与提升,这乃是每一位笔者的初衷

感谢您的阅读 欢迎您的留言与建议

第5篇-JAVA面向对象Ⅰ
第7篇-JAVA面向对象Ⅲ
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }