5、面向对象编程(上)

面向对象内容的三条主线

1.Java类及类的成员:属性、方法、构造器;代码块、内部类

2.面向对象的三大特征:封装性、继承性、多态性、(抽象性)

3.其它关键字:this、super、static、final、abstract、interface、package、import等

说明: untitle.png

面向对象的思想概述

说明: untitle.png

Java语言的基本元素: 类和对象

说明: untitle.png

说明: untitle.png

类的设计原则

UML类图

说明: ScreenClip.png

类的结构一:属性

属性(成员变量)vs局部变量

相同点

1、定义变量的格式是一样的:数据类型 变量名 = 变量值

2、先声明,后使用

3、变量都有其对应的作用域

不同点

1、在类中声明位置的不同

属性:直接定义在类的一对{}

局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

2、关于权限修饰符的不同

属性:可以在声明属性时,指明其权限,使用权限修饰符

常用的权限修饰符:private(私有)、pubilc、缺省、protected

局部变量:不可以使用权限修饰符

3、默认初始化值的情况

属性:类的属性,根据其类型,都有默认初始化值

整形(byte、short、int、long):0

浮点型(double、float):0.0

字符型(char):0(或\u0000

布尔型(boolean):false

引用数据类型:null

局部变量:没有默认初始化值

意味着,调用局部变量之前,一定要显示赋值

特别的,形参在调用时,赋值即可

4、在内存中加载的位置不同

属性:加载在堆空间中

局部变量:加载在栈空间

类的结构二:方法

方法:描述类应该具有的功能,比如:

Math类:sqrt(),random()...

Scanner类:nextXxx()...

Arrays类:sort(),binarySearch(),toString(),equals()...

方法的分类

说明: untitle.png

方法的声明格式

说明: untitle.png

public static void main (String[] args){ // 方法体 }
//权限修饰符:private \缺省 \protected \pubilc ----> 封装性
//修饰符:static \ final \ abstract \native 可以用来修饰方法
//返回值类型: 无返回值 / 有返回值 --> return
//方法名:需要满足标识符命名的规则、规范;"见名知意"
//形参列表:重载 vs 重写;参数的值传递机制;体现对象的多态性
//方法体:来体现方法的功能
return关键字的使用

使用范围:使用在方法体中

作用:

1、结束方法

2、针对于有返回值类型的方法,使用return 数据方式,返回需要的数据

注意点:return关键字后面不可以声明执行语句

注意

方法的使用中,可以调用当前类的属性和方法。

方法中不可以定义方法。

方法的重载

定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。

总结:"两同一不同":类、相同方法名,相同

​ 参数列表:参数个数、参数类型,参数顺序,不同

方法的重载和方法的权限修饰符、返回值类型、形参变量名、方法体都没关系!

可变个数的形参(JDK5.0新增)
声明格式

方法名(参数的类型名 ...参数名)

例如:public void st(String ... a);

1、可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个

2、可变个数形参的方法与同名的方法之间,彼此构成重载

3、可变参数方法的使用与方法参数部分使用数组是一致的

4、方法的参数部分有可变形参,需要放在形参声明的最后

5、在一个方法的形参位置,最多只能声明一个可变个数形参

方法参数的值传递机制

方法,必须由其所在类或对象调用才有意义。若方法含有参数:

形参:方法声明时的参数

实参:方法调用时实际传给形参的参数值

Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本 (复制品)传入方法内,而参数本身不受影响。

方法的递归

递归方法:一个方法体内调用它自身。

方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。

递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

类的结构三:构造器

构造器(或构造方法):Constructor

构造器的作用

1.创建对象

2.初始化对象的信息

说明
  1. 如果没显式的定义类的构造器的话,则系统默认提供一个空参的构造器

  2. 定义构造器的格式:权限修饰符 类名(形参列表){}

  3. 一个类中定义的多个构造器,彼此构成重载

  4. 一旦我们显式的定义了类的构造器之后,该类就不再提供默认的空参构造器

  5. 一个类中,至少会有一个构造器。

创建对象的执行顺序

1、给属性开辟空间,给属性赋默认值

2、如果声明属性的时候给属性赋初始值,那么接下来会给属性赋初始值

3、如果类中有代码块,会执行代码块(每创建一次对象都会执行一次)

4、调用构造方法

类的结构四:代码块

代码块的作用

用来初始化类、对象的信息

代码块要是使用修饰符,只能使用static

对象

没有完全相同的两个对象,对象具有唯一性(内存)!

说明: untitle.png

说明: untitle.png

类和对象的使用(面向对象思想落地的实现)

1、创建类、设计类的成员

2、创建类的对象new Constuctor()

3、通过对象.属性对象.方法()调用对象的结构

如果创建了一个类的多个对象,对于类中定义的属性,每个对象都拥有各自的一套副本,且互不干扰。意味着:如果修改一个对象的属性A,则不影响另一个对象的属性A的值。

对象的产生的内存解析

说明: untitle.png

对象数组的内存解析

说明: untitle.png

面向对象特征一:封装性

概念

隐藏复杂,暴露简单

隐藏对象的属性和实现细节,仅对外提供公共访问方式,将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。

好处

(1)只能通过规定的方法访问数据,可以有效的保护数据

(2)隐藏类的实现细节,方便修改和实现。

封装的实现步骤

(1)修改属性的可见性设为private

(2)创建getter/setter方法(用于属性的读写)(通过这两种方法对数据进行获取和设定,对象通过调用这两种发方法实现对数据的读写)

(3)在getter/setter方法中加入属性控制语句(对属性值的合法性进行判断)(不是必须要加)

四种访问权限修饰符

权限从小到大顺序为:private < 缺省 < protected < public

可见范围

修饰符 类内部 同一个包 不同包的子类 同一个工程
private yes
缺省(default) yes yes
protected yes yes yes
public yes yes yes yes

4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类

修饰类的话,只能使用:缺省、public

Java中关于对象的名词

关键字:this

概念

this理解为:当前对象当前正在创建的对象

在类的方法中,我们可以使用this.属性this.方法的方式,调用当前对象属性或方法。但是,通常情况下,我们都择省略this.

特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。

this调用构造器

  1. 我们在类的构造器中,可以显式的使用this(形参列表)方式,调用本类中指定的其他构造器

  2. 构造器中不能通过this(形参列表)方式调用自己

  3. 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了this(形参列表)

  4. 规定:this(形参列表)必须声明在当前构造器的首行

  5. 构造器内部,最多只能声明一个this(形参列表),用来调用其他的构造器

关键字:final

作用范围

可以用来修饰:类、方法、变量

说明

final 用来修饰一个类:此类不能被其他类所继承。

​ 比如:String类、System类、StringBuffer类

final 用来修饰方法:表明此方法不可以被重写

​ 比如:Object类中getClass();

final 用来修饰变量:此时的“变量”就称为是一个常量

​ 1. final修饰属性:可以考虑赋值的位置:显式初始化、代码块中初始化、构造器中初始化,但是只可以三选一,final修饰的属性不可以提供setter方法!

​ 2. final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。

static final 用来修饰属性:全局常量

包(package)

概念

  1. 为了更好的实现项目中类的管理,提供包的概念
  2. 使用package声明类或接口所属的包,必须声明在源文件的首行
  3. 包,属于标识符,遵循标识符的命名规则、规范xxxyyyzzz、“见名知意”
  4. .一次,就代表一层文件目录。

JDK中的主要包

说明: untitle.png

import的使用:

import:导入

  1. 在源文件中显式的使用import结构导入指定包下的类、接口
  2. 声明在包的声明和类的声明之间
  3. 如果需要导入多个结构,则并列写出即可
  4. 可以使用xxx.*的方式,表示可以导入xxx包下的所有结构,但是如果使用的是xxx子包下的结构,则仍需要显式导入
  5. 如果使用的类或接口是java.lang(java的默认导入包)包下定义的,则可以省略import结构
  6. 如果使用的类或接口是本包下定义的,则可以省略import结构
  7. 如果在源文件中,使用了不同包下的同名的类,则必须至少一个类需要以全类名的方式显示。
  8. import static:导入指定类或接口中的静态结构:属性或方法。

出血模型

定义:

简单来说,失血模型就是一个类,只有私有属性以及属性的getter/setter的纯数据类,所有业务逻辑都由Business Object来完成。

优势:

实现了业务与数据的完全分离,降低了代码之间的耦合

单一职责

一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离