本周主题:面向对象程序设计(二)

   JAVA面向对象三大特性:

​一、Java 封装​

​二、Java 继承​

​三、Java 多态​


一、Java 封装

1、封装的概念

在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

2、封装的优点

  1. 良好的封装能够减少耦合。
  2. 类内部的结构可以自由修改。
  3. 可以对成员变量进行更精确的控制。
  4. 隐藏信息,实现细节。

3、实现Java封装的步骤

  1. 修改属性的可见性来限制对属性的访问(一般限制为private),属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
  2. 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问。即提供get()和set()方法。

4、举个例子:

    1、对Student类中的成员变量进行封装:

/**
* 文件名:Student.java
* 功能描述:类的封装演示,get()、set()使用方法
*
*/
class Student{
private String name; //姓名
private char sex; //性别
private int age; //年龄

public Student() {

}

public Student(String name,char sex,int age) {
setName(name);
setSex(sex);
setAge(age);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public void setSex(char sex) {
if (sex == '男' || sex == '女')
this.sex = sex;
else {
System.out.println("性别必须为【男】或【女】!");
this.sex = '男';
}
}

public char getSex() {
return sex;
}

public int getAge() {
return age;
}

public void setAge(int age) {
if (age>=18 && age <= 60) {
this.age = age;
}
else {
this.age = 18;
System.out.println("年龄不合法!");
}

}

public void show(){
System.out.printf("姓名:%s, 性别:%s, 年龄:%d\n",name,sex,age);
}

}

    2、 测试类:

/**
* 文件名:StudentTest.java
* 功能描述:类的封装测试用例
*
*/
public class StudentTest {
public static void main(String[] args) {

String name = "张三丰";
char sex = '男';
int age = 21;

Student stu1=new Student(name,sex,age);
stu1.show();
}
}

    3、运行结果: 

第八周Java作业_java

二、Java 继承


1、继承的概念

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

生活中的继承:

第八周Java作业_封装_02

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。

所以继承需要符合的关系是:is-a,父类更通用,子类更具体。

虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。

2、类的继承格式

在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:

class 父类 { 

}

class 子类 extends 父类 {

}

3、继承类型

需要注意的是 Java 不支持多继承,但支持多重继承。

4、继承的特性

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

5、继承关键字

继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

  1. extends 关键字
  2. implements关键字
  3. super 与 this 关键字
  4. final关键字

6、举个例子

案例分析:

/*
某公司雇员示例:
需求:
        程序员 :姓名,工号,薪水,工作内容,开发语言
        项目经理:姓名,工号,薪水,工作内容,还有奖金
        对给出需求进行数据建模
分析:

        在这个问题领域中,先找出涉及的对象。

        通过名词进行提炼:
        程序员:
            属性:姓名,工号,薪水,开发语言
            行为:工作
        项目经理:
            属性:姓名,工号,薪水,奖金
            行为:工作

        程序员和经理不存在直接继承关系
        但是程序员和经理却具有共性内容
        因此可设计一个共同的抽象类(雇员类Employee),由它派生并实现程序员类(Programmer)和经理类(Manager)
*/

父类---Employee(雇员)

/**
* 文件名:Employee.java
* 功能描述:雇员类(抽象类)
*/
abstract class Employee {
String name; //姓名
String id; //工号
double pay; //薪水

Employee(String name,String id,double pay) {
this.name = name;
this.id = id;
this.pay = pay;
}

void showInfo() {
System.out.println(String.format("工号:%s,姓名:%s,薪水:%,.2f",id,name,pay));
}

public abstract void work();
}

子类1---Manager(经理)

/**
* 文件名:Manager.java
* 功能描述:经理类
*/
class Manager extends Employee {
double bonus; //奖金
public Manager(String name,String id,double pay,double bonus) {
super(name,id,pay);
this.bonus = bonus;
}

public void work() {
System.out.println(this.getClass()+":");
showInfo();
System.out.println(String.format("我是一名经理,我的奖金是:%,.2f",bonus));
}
}

子类2---Programmer(程序员)

/**
* 文件名:Programmer.java
* 功能描述:程序员类
*/
class Programmer extends Employee{
String developmentLanguage; //开发语言
public Programmer(String name,String id,double pay,String developmentLanguage) {
super(name,id,pay);
this.developmentLanguage = developmentLanguage;
}

public void work() {
System.out.println(this.getClass()+":");
showInfo();
System.out.println(String.format("我是一名程序员,我的开发语言是:%s",developmentLanguage));
}

}

测试类---ClassTest 

/**
* 文件名:AbstractTest.java
* 功能描述:对Employee/Manager/Programmer进行测试
*/
public class AbstractTest {
public static void main(String[] args) {
Manager m = new Manager("张三丰子", "1001", 12000.00, 6000.00);
m.work();

Programmer p = new Programmer("小宇飞刀", "2001", 9500.00,"Java");
p.work();
}
}

 运行结果:

  

第八周Java作业_封装_03

三、Java 多态


1、多态的概念

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:

第八周Java作业_封装_04

多态性是对象多种表现形式的体现。

现实中,比如我们按下 F1 键这个动作:

  • 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
  • 如果当前在 Word 下弹出的就是 Word 帮助;
  • 在 Windows 下弹出的就是 Windows 帮助和支持。

同一个事件发生在不同的对象上会产生不同的结果。

2、多态的优点

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

3、多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

4、多态的实现方式

  • 方式一:重写
  • 方式二:接口
  • 方式三:抽象类和抽象方法

5、举个例子

改造上一Demo

对上一个例子中的测试类进行改造,利用类多态特性,使用同一个对象变量对不同的对象方法进行调用。Employee.java、Manager.java和Programmer.java的内容不变。

/**
* 文件名:AbstractTest.java
* 功能描述:对Employee/Manager/Programmer进行测试
*/
public class AbstractTest {
public static void main(String[] args) {
Manager m = new Manager("张三丰子", "1001", 12000.00, 6000.00);
m.work();

Employee em = m;//声明了一个Employee的变量并赋值,它是Manager和Programmer的父类
//因为Employee中并无bonus成员,故必须对em进行类型判断,只有类型转换后才能访问bonus成员
if(em instanceof Manager) {
((Manager) em).bonus = 3500;
}
em.work();

em = new Programmer("小宇飞刀", "2001", 9500.00,"Java");
em.work();

}
}

运行结果:

   

第八周Java作业_父类_05

 

四、演示DEMO源代码在github上的仓库地址:

​https://github.com/xieyunc/java_demo.git​