本周主题:面向对象程序设计(二)
JAVA面向对象三大特性:
一、Java 封装
1、封装的概念
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
2、封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
3、实现Java封装的步骤
- 修改属性的可见性来限制对属性的访问(一般限制为private),属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
- 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问。即提供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 继承
1、继承的概念
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
生活中的继承:
兔子和羊属于食草动物类,狮子和豹属于食肉动物类。
食草动物和食肉动物又是属于动物类。
所以继承需要符合的关系是: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)祖先类。
- extends 关键字
- implements关键字
- super 与 this 关键字
- 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 多态
1、多态的概念
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:
多态性是对象多种表现形式的体现。
现实中,比如我们按下 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();
}
}
运行结果:
四、演示DEMO源代码在github上的仓库地址:
https://github.com/xieyunc/java_demo.git