面向对象
- 面向对象编程(OOP —— Object Oriented Programing)
什么是面向过程、面向对象?
面向过程与面向对象都是我们编程中编写程序的一种思维方式
Ⅰ.面向过程的程序设计方式,是遇到一件事时,思考"我该怎么做",然后一步步实现的过程。
例如:公司打扫卫生(擦玻璃、扫地、拖地、倒垃圾等),按照面向过程的程序设计方式会思考"打扫卫生我该怎么做,然后一件件的完成",最后把公司卫生打扫了个干净
Ⅱ.面向对象的程序设计方式,是遇到一件事时,思考"我该让谁来做",然后那个"谁"就是对象。他要怎么做这件事是他自己的事,反正最后一群对象合力能把事做好就行了
例如:公司打扫卫生(擦玻璃、扫地、拖地、倒垃圾等),按照面向对象的程序设计方式会思考“我该让谁来做,如小明擦玻璃,小丽扫地,小郭拖地,小李倒垃圾等”,他们合力把卫生打扫干净
Ⅲ.买电脑(组装机)
先使用面向过程说明买电脑这件事:
我去网上查询参数和报价,电脑城询价,现场安装和监督,抱电脑回家。在这整个过程中我参与了每一个细节,并且会感觉相当累。
使用面向对象说明买电脑这件事:
首先找一个懂电脑硬件的人,让他来帮我查询参数和报价,并进行询价和砍价,以及现场组装和监督。而我不需要亲历亲为,我只需要告诉这个人我的需求就可。
面向对象思维方式的好处
通过生活中的真实场景使用面向对象分析完之后,我们开始分析面向过程和面向对象的差异做出总结:
Ⅰ.面向对象思维方式是一种更加符合人们思考习惯的思想
Ⅱ.面向过程思维方式中更多体现的是执行者(自己做事情),面向对象中更多体现的是指挥着(指挥对象做事情)
Ⅲ.面向对象思维方式将复杂的问题简单化
面向对象举例
身边的对象:
身边的对象:
超市:
客户:
姓名:张浩
身高:180cm
体重:60kg
操作 : 购物
收营员:
姓名:李明
部门:财务部
员工编号: 001
操作:收银、打印账单、刷卡
对象的特征:
属性 —— 对象具有的各种特征
每个对象的每个属性都有特定值
方法 —— 对象执行的操作
对象:用来描述客观事物的一个实体,由一组属性和方法构成
属性(名词)就这个对象是有什么,方法(动词)就是这个对象可以做什么
我们来看:
列出尼古拉斯·凯奇驾驶的这辆法拉利F360 Spider的属性和方法
属性:
品牌:法拉利
颜色:黄色
价格:380W
型号:F360 Spider
方法:
发动
加速
停止
再来看:
列出小狗的属性与方法:
属性:
颜色: 白色
体重:7kg
方法:
叫
跑
吃
对象同时具有属性与方法两项特性
对象的属性与方法通常被封装到一起,用属性与方法来共同体现事物的特性,二者相辅相成
说一说教师里面的对象,描述他们的属性与方法
对象在代码中的体现
在分析现实生活中的事物时发现,这些事物都有其具体的特点和功能,这些特点和功能就组成了这个特殊的事物
我们来描述一辆小汽车:
分析:
事物的特点(属性):
颜色
轮胎个数
事物的功能:
运行
发现:事物其实就是由特点(属性)和行为(功能)组成的。
可以简单的理解:属性就是数值,其实就是变量;行为就是功能,就是方法。
小汽车{
颜色;
轮胎个数;
运行(){};
}
通过计算机语言java开描述这个事物
定义类的格式:
汽车类:
public class car{
String color;//颜色
int number;//轮胎个数
//行驶
public void run(){
System.out.println("一辆颜色为"+color+"轮子数为"+number+"的车行驶在蜿蜒的马路上");
}
}
通过代码的描述,知道类的真正意义就是在描述事物。属性和功能统称为事物中的成员。
事物的成员分为两种: 成员属性和成员功能。
成员属性在代码中体现就是成员变量
成员功能在代码中体现就是成员方法
把写好的代码测试一下。需要一个独立运行类
测试类:
public class CarDemo(){
/*
* 测试:Car类中的run方法
*/
// 1.创建Car对象,给对象起个名字
public staic void main(String[] args){
Car c = new Car();
// c是类的类型变量,c指向了一个具体的Car类型的对象
// 通过已有的对象调用该对象的功能。格式:对象.对象成员; //可以给对象的属性赋值
c.color = "blue";
c.number = 4;
c.run();
}
}
类和对象的区别
面向对象的编程思想力图在程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出两个概念,即类和对象。其中,类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体
如下图所示:
将玩具模型看作是一个类,将一个个玩具看作对象,从玩具模型和玩具之间的关系便可以看出类与对象之间的关系。类用于描述多个对象的共同特征,它是对象的模板。对象用于描述现实中的个体,它是类的实例。从上图中可以明显看出对象是根据类创建的,并且一个类可以对应多个对象,接下来分别讲解什么是类和对象
创建对象使用关键字 new
局部变量与成员变量
区别一:定义的位置不同
定义在类中的变量是成员变量
定义在方法中或者{}语句里面的变量是局部变量
区别二:在内存中的位置不同
成员变量存储在对内存的对象中
局部变量存储在栈内存的方法中
区别三:声明周期不同
成员变量随着对象的出现而出现在堆中,随着对象的消失而从堆中消失
局部变量随着方法的运行而出现在栈中,随着方法的弹栈而消失
区别四:初始化不同
成员变量因为在堆内存中,所有默认的初始化值
局部变量没有默认的初始化值,必须手动的给其赋值才可以使用
面向对象三大特性
-
封装
- 只隐藏对象的属性和实现细节,仅对外提供公共访问方式
- 好处
- 将变化隔离、便于使用、提高复用性、提高安全性
- 原则
- 将不需要对外提供的内容隐藏起来;把属性隐藏,提供公共方法对其访问
-
继承
- 子类自动拥有父类非私有的属性与方法
- 提高代码复用性;继承是多态的前提
-
多态
- 类的多种形态。是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象
- 好处
- 提高了程序的扩展性
- 弊端
- 当父类引用指向子类对象时,虽提高了扩展性,但只能访问父类中具备的方法,不可访问子类中的方法;即访问的局限性
- 前提
- 实现或继承关系;覆写父类方法
面向对象设计原则
- 开 : 开闭原则)
- 口 : 接口隔离原则
- 合 : 组合|聚合原则
- 里 : 里式替换原则
- 最 : 最少知识原则(迪米特法则)
- 单 : 单一职责原则
- 依 : 依赖倒置原则
TDD(Test Driver Devolepment ) 测试驱动编程
- TDD 测试驱动编程, 编程方法学,编程思想
* DDD(Domain-driven design) 领域驱动设计
优劣:
保证了代码质量,测试的覆盖率高。开发效率低
测试: 本身也是一套完整的学科 单元测试 白盒测试:能看到源码 黑盒测试:没有源码,功能测试 灰盒测试:基于白盒与黑盒之间的测试,通过一些表征性的现象、事件、标志来判断内部的运行状态 压力测试: 并发数的问题,能承载多少并发 疲劳强度测试: 长期稳定运行,72小时 7天 冒烟测试: 对某一个功能疯狂的测试,主要流程(支付环节) 集成测试: 完整功能测试,最重要测试整体业务流程 回归测试: 增加一个功能(重新测试) 自动化测试: 编码,场景设计(模拟场景,设计编码) 代码评审: 看有没有留后门
JUnit简介
-
JUnit 是用于编写和运行可重复的自动化测试的开源测试框架,这样可以保证我们的代码按预期工作。JUnit 可广泛用于工业和作为支架(从命令行)或IDE(如 IDEA)内单独的 Java 程序
-
JUnit 提供
- 断言测试预期结果
- 测试功能共享通用的测试数据
- 测试套件轻松地组织和运行测试
- 图形和文本测试运行
-
JUnit 用于测试
-
整个对象
-
对象的一部分 - 交互的方法或一些方法
-
几个对象之间的互动(交互)
-
-
JUnit 特点
-
JUnit 是用于编写和运行测试的开源框架
-
提供了注释,以确定测试方法
-
提供断言测试预期结果
-
提供了测试运行的运行测试
-
JUnit 测试让您可以更快地编写代码,提高质量
-
JUnit 是优雅简洁。它是不那么复杂以及不需要花费太多的时间
-
JUnit 测试可以自动运行,检查自己的结果,并提供即时反馈。没有必要通过测试结果报告来手动梳理
-
JUnit 测试可以组织成测试套件包含测试案例,甚至其他测试套件
-
Junit 显示测试进度的,如果测试是没有问题条形是绿色的,测试失败则会变成红色
-
- JUnit 注解
注解 | 描述 |
---|---|
@Test public void method() | 测试注释指示该公共无效方法它所附着可以作为一个测试用例。 |
@Before public void method() | Before 注释表示,该方法必须在类中的每个测试之前执行,以便执行测试某些必要的先决条件 |
@BeforeClass public static void method() | BeforeClass 注释指出这是附着在静态方法必须执行一次并在类的所有测试之前。发生这种情况时一般是测试计算共享配置方法(如连接到数据库)。 |
@After public void method() | After 注释指示,该方法在执行每项测试后执行(如执行每一个测试后重置某些变量,删除临时变量等) |
@AfterClass public static void method() | 当需要执行所有的测试在 JUnit 测试用例类后执行,AfterClass 注解可以使用以清理建立方法,(从数据库如断开连接)。注意:附有此批注(类似于 BeforeClass)的方法必须定义为静态。 |
@Ignore public static void method() | 当想暂时禁用特定的测试执行可以使用忽略注释。每个被注解为 @Ignore 的方法将不被执行。 |
-
JUnit 断言
-
什么是断言
-
断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。
-
使用断言可以创建更稳定、品质更好且 不易于出错的代码。当需要在一个值为 false 时中断当前操作的话,可以使用断言。单元测试必须使用断言(Junit/JunitX)。
-
-
常用断言方法
断言 | 描述 |
---|---|
void assertEquals([String message], expected value, actual value) | 断言两个值相等。值可能是类型有 int, short, long, byte, char or java.lang.Object. 第一个参数是一个可选的字符串消息 |
void assertTrue([String message], boolean condition) | 断言一个条件为真 |
void assertFalse([String message],boolean condition) | 断言一个条件为假 |
void assertNotNull([String message], java.lang.Object object) | 断言一个对象不为空(null) |
void assertNull([String message], java.lang.Object object) | 断言一个对象为空(null) |
void assertSame([String message], java.lang.Object expected, java.lang.Object actual) | 断言,两个对象引用相同的对象 |
void assertNotSame([String message], java.lang.Object unexpected, java.lang.Object actual) | 断言,两个对象不是引用同一个对象 |
void assertArrayEquals([String message], expectedArray, resultArray) | 断言预期数组和结果数组相等。数组的类型可能是 int, long, short, char, byte or java.lang.Object. |
/**
* 测试断言
*/
@Test
public void testAssert() {
String obj1 = "junit";
String obj2 = "junit"; String obj3 = "test"; String obj4 = "test"; String obj5 = null; int var1 = 1; int var2 = 2; int[] arithmetic1 = {1, 2, 3}; int[] arithmetic2 = {1, 2, 3}; assertEquals(obj1, obj2); assertSame(obj3, obj4); assertNotSame(obj2, obj4); assertNotNull(obj1); assertNull(obj5); assertTrue("为真", var1 == var2); assertArrayEquals(arithmetic1, arithmetic2); }
封装
封装有两层含义:
1.对功能的封装,比如我们的方法,方法就是一个功能的实现
2.对数据的封装,就比如手机的价格、屏幕等
封装的表现:
1.方法就是一个最基本的封装
2.类其实就是一个封装体
封装的好处:
1.提高了代码的复用性
2.影藏实现细节,对外提供可以访问的方法。便于使用者去使用,这是核心之一,也就是理解为封装的概念。
3.提高了安全性
-
封装举例:
- 比如人:
- 属性:
- 姓名
- 年龄
- 方法:
- 吃饭
- 属性:
- 比如人:
不私有化属性:
public class Person{
String name;
int age;
public void eat(){
System.out.println(name+"在吃饭")
}
}
public class PersonDemo(){
public static void main(){ //创建Person的对象 Person person = new Person(); person.name="人妖"; person.age = "18"; p.eat(); }
}
通过上述代码,我们用Java代码把Person描述清楚了,但有个严重的问题,就是Person中的属性是可以用直接访问的。
怎么才能不让直接访问呢?
需要使用java中的一个关键字private(私有,权限修饰符)。只要将Person的属性和行为私有起来,这样就无法直接访问。
私有化属性:
public class Person{
private String name;
private int age; /* 提供set与get方法 */ public void setName(String name){ this.name = name;//this代表本类对象 } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public int getAge(){ return this.age; } public void eat(){ System.out.println(name + "在吃饭"); } } public class PersonDemo{ public static void main(String[] args){ Person person = new Person(); //现在 person.name = "人妖";是行不通的,那我们要肿么办呢? person.setName("小则"); } }
总结:
类中不需要对外提供的内容都私有化,包括属性和方法。
以后再描述事物,属性都私有化,并提供setXxx getXxx方法对其进行访问。
注意:私有仅仅是封装的体现形式而已