# 面向对象编程
[TOC]
## 面向过程和面向对象编程
例如 C 语言、VB 语言都是面向过程的编程语言。通过一个函数(方法)解决一件事情,「就事论事」。事情处理完成后,是不会留下任何「遗产」的。
一件事情:
例如 「南通渡课 IT 教育 Java班同学在 1 教室上李老师的 Java 课」。
用面向对象的思维逻辑去分析,抽象实体:
* 班级
* 学生
* 教室
* 老师
* 课程
* 学校
通过类封装实体的属性和动作(方法)。
## 类与对象
**类**: 是一种自定义的数据类型。有时把这种数据类型也叫做「类类型」或者「引用数据类型」。「引用」就是内存地址的意思。
**对象**:通过类创建的变量,或者叫类的实体。
>[success] 类是一群对象的特征母版,对象是类的具体实例。
> 类是一群对象的抽象。
### 类的定义
>[warning] 类所具备的最基本要素:(静态)属性、(动态)方法。
语法:
~~~
[修饰符] class 类名 {
// 成员变量
[修饰符] 数据类型 成员变量1;
[修饰符] 数据类型 成员变量2;
...
// 方法
[修饰符] 返回值 方法名1([参数列表]) {
方法体语句;
}
[修饰符] 返回值 方法名2([参数列表]) {
方法体语句;
}
...
// 构造器:创建对象用的方法
[修饰符] 类名([参数列表1]) {
方法语句;
}
[修饰符] 类名([参数列表2]) {
方法语句;
}
}
~~~
### 类的三大组成部件
**类的三大部件:成员变量、方法、构造器。**
示例:
~~~
public class Student1 {
// 构造器
Student1(String name, int age, String code) {
this.name = name;
this.age = age;
this.code = code;
}
// 成员变量
String name;
int age;
String code;
// 方法
String intro() {
return "我叫"+this.name+",我的学号是"+this.code+",我今年"+this.age+"岁了。";
}
void listen() {
System.out.println(this.name + "在上课。");
}
}
~~~
### 使用类构建对象
~~~
public static void main(String[] args) {
// 构建一个对象:调用类的构造器
Student1 hehao = new Student1("何浩", 20, "C25");
// 用对象:给属性赋值
hehao.birthday = new Date(); // 赋值
System.out.println(hehao.code); // 获取属性值
// 用对象:调用对象的方法
System.out.println(hehao.intro());
hehao.listen();
}
~~~
>[info] 类名的定义要符合 Java 的标识符命名规范,类名首字母大写,如果多个单词,使用驼峰命名法则(每个独立单词首字母大写),**在 Java 中,只要看到首字母大写,你就是一个类。**
> 类中三大部件的定义是没有严格的顺序的,但是,我们一般遵循,构造器、成员变量、方法这样的定义顺序。
## 构造器
语法:
~~~
[修饰符] 类名([参数列表]){}
~~~
* 构造器本身是一个比较特殊的方法,方法名就是类名,没有返回值(和void是有区别的),构造器是类创建对象的唯一途径。如果一个类没有显示的定义一个构造器,那么编译器就会给这个类默认定义一个没有参数的构造器。
* 如果显示的定义了一个构造器,那么**编译器就不会给这个类定义默认的构造器**
## 成员变量
语法:
~~~
[修饰符] 数据类型 成员变量名 [=默认值]
~~~
* 修饰符:可以省略,也可以是public /protected / private / static / final ,其中public protected private 只允许出现其中的一个。
* 数据类型:可以是任意的数据类型。(包含基本数据类型,类类型,数组类型)
* 默认值:如果是类类型的,没有定义默认值,那么成员变量的值为null,如果是基本数据类型,没有定义默认值,那么成员变量的值是有意义的,比如说int类型的值就是0,boolean类型的值就是false。
## 方法
语法:
~~~
[修饰符] 方法的返回值的数据类型 方法名([形参列表]) {
方法体语句;
}
~~~
* 修饰符:可以省略,也可以是public /protected / private / static / final ,其中public protected private 只允许出现其中的一个。
* 返回值: 可以是数据类型(不要忘了自定义个数据类型),也可以是void,如果我们定义了返回值,那么久必须在**return后面跟随该类型的值或对象**
* 方法名: 一般是首字母小写,也适用驼峰原则,一般是动词在前,名词在后,不易过长。
* 形参列表: 定义方法可以接受的参数,由0个-n个\[数据类型 参数名\] 通过\*\*,\*\*进行组合,一旦这个方法指定了形参,那么在调用的时候就必须一一对应的传入参数(实际参数)
关于参数的补充说明:
1. 实参:是确定数字,文字,数组等实际内容,所以称之为实际参数。多用于在调用这个方法的时候传入实际参数。
2. 形参:形参是形式参数的简称。它只是一种形式,不是具体的值。相当于数学中的代数,代表着一个数而已。
2.1 形参的作用:
* 定义了一个局部的变量,在方法的内部可以调用
* 外部调用这个方法的时候,告诉调用者这个方法需要什么样的参数。
## static 关键字
用于修饰成员变量和方法。用static修饰的成员变量和方法,是属于**类**的,而不是属于该**类的实例(对象)**。
通常我们把static修饰的成员变量称之为【类变量,静态变量】,方法称之为【类方法,静态方法】
>[danger] 静态的成员是不能访问非静态成员的
> 静态成员之间是可以相互访问的
~~~
public static int age=18;
static String fun() {
System.out.println(age);
return "";
}
String fun2() {
System.out.println(this.age);
return "";
}
~~~
## 使用一个对象的过程
* 定义类
* 构建和使用对象
语法:
~~~
类类型 对象名 = new 构造器方法();
~~~
实例:
~~~
Person dongdong = new Person();
~~~
**在内存中的执行过程**
1. 在栈内存中,会存储对象名, 在没有执行构造器创建对象并赋值是,此时对象名对应的值应为null
2. 通过new关键字调用类的构造器在堆内存中分配了一块对象区域;
3. 通过赋值运算符= ,将堆内存中的对象地址赋给栈内存中的变量名;
4. 例如再次给对象的属性赋值: 通过栈内存中的地址定位到对象在堆内存中的地址,找到相应的成员变量,进行一个赋值操作
>[info] 引用: 引用还可以称之为【地址】,【指针】 。特指的示类类型。因为只用类类型才会在堆内存中分配对象空间,并将地址(指针)在栈内存中用于对象变量名的引用。
## this关键字
Java中使用this关键字,指向调用该方法的对象。根据this所在的位置,大致分为两种情况
* 出现在构造器中:引用该构造器正在初始化的对象
* 出现在普通方法中: 正在调用该方法的对象
this用在类定义中,获取当前对象的属性,或者调用当前对象的方法
>[warning]在类定义中,可以省略this关键字去调用属性或者方法,但是在类被编译的时候,编译器还是会加上this关键字。所以我们强烈建议在类定义的时候如果要调用该类中的普通成员变量或者方法,还是要把this给加上去
> 用static修饰的方法是不能使用this关键字的
~~~
public class Students {
public static void main(String[] args) {
Students ding = new Students("丁润萌","001",18);
ding.listen();
System.out.println(ding.fun1());
}
String name;
String code;
int age;
public Students(String name, String code, int age) {
super();
this.name = name;
this.code = code;
this.age = age;
}
public Students() {
super();
}
/**
* 自我介绍
* @return
*/
String intro() {
return "我叫" + this.name + ", 我的学号是" + this.code + ", 我今年" + this.age + "岁了";
}
void listen() {
System.out.println("自我介绍" + this.intro() + " " + this.name + "正在上课");
}
//错误实例
/*static String fun2() {
return this.intro();
}*/
static String fun() {
return "Hello,world";
}
//错误实例
String fun1() {
this.fun();
return "Hello";
}
}
~~~