Java 面向对象编程(基础)

Java 面向对象编程(基础)
sinarcsinx面向对象是一种开发软件的方法,使分析、设计和实现一个系统的方法尽可能接近人们认识一个系统的方法。包括三个方面:面向对象分析、面向对象设计、面向对象程序设计。
Java 语言是纯面向对象的语言。其所有数据类型都有相应的类,程序可以完全基于对象编写。
类与对象(OOP)
类 就是数据类型。可以是
int也可以是人类对象 就是其中具体的实例。可以是
100从 类 到 对象,可以称为 创建一个对象,也可以说 实例化一个对象,或者 把对象实例化
- 类 是抽象的、概念的,代表一类事物
- 对象 是具体的、实际的,代表一个个具体事物
- 类 是 对象 的模板,对象 是 类 的一个个体,对应一个实例
下面,我们定义了一个类 Cat 并创建了一些 对象 cat1 cat2:
1 | public class Code6_1{ |
属性/成员变量
从概念或叫法上看:成员变量 = 属性 = field(字段)
1 | class Cat{ |
其中,String name; 就是一个成员变量(属性)。
属性可以是基本数据类型,也可以是引用数据类型。
- 属性的定义语法同变量。
访问修饰符 属性类型 属性名- 访问修饰符:控制属性的访问范围。有四种:
publieprotected默认(空)private
- 访问修饰符:控制属性的访问范围。有四种:
- 属性的定义类型可以为任意类型,包含 基本类型 或 引用类型
- 属性如果不赋值,有默认值。规则同 Java 数组、排序和查找
创建对象
先声明再创建:
1
2Cat cat1; //声明对象cat1
cat1 = new Cat(); //创建对象直接创建:
1
Cat cat2 = new Cat();
注意事项:
声明对象的场合,只是在内存中建立了一个引用。此时,该地址引用不指向任何内存空间。
对象的引用,也被称为对象的句柄。
使用 new 运算符创建对象实例时,会为对象分配空间,就会调用类的构造方法。那之后,会将该段内存的首地址赋给刚才建立的引用。
访问对象
基本语法:对象名.属性名
1 | System.out.println(cat1.name); |
在Java中,任何对象变量的值都是对储存在另外一个地方的某个对象的引用。
类与对象的内存访问机制
栈:一般存放基本数据类型(局部变量)
堆:存放对象(如
Cat cat1 = new Cat(),是在这里开辟的空间)方法区:常量池(常量,比如字符串),类加载信息
- 创建对象时,先加载 类 信息,然后在 堆 中分配空间,栈 中的对象名被赋予指向那个空间的地址。
- 之后进行指定初始化。该对象的 属性 中,是 基本数据类型 的直接记录在 堆 中;是 字符串 的记录一个地址,该地址指向 方法区,那里的常量池有该字符串。
成员方法
在某些情况下,我们需要定义成员方法。比如 Cat 除了有属性(name age)外,还可以有一些行为比如玩耍。
1 | 修饰符 返回数据类型 方法名(形参列表){ |
方法名必须是一个合法的标识符
返回类型即返回值的类型。如果方法没有返回值,应声明为 void
修饰符段可以有几个不同的修饰符。
1
2
3public static strictfp final void method() {
System.out.println("哎咿呀~ 哎咿呀~");
}其中 public(访问修饰符)、static(static 关键字)、final(final 关键字)
—— 访问修饰符见 Java 面向对象编程(中级)
—— static 关键字见 Java 面向对象编程(高级)
—— final 关键字见 Java 面向对象编程(高级)
—— strictfp 关键字见 Java 常用类
参数列表是传递给方法的参数表。各个元素间以
,分隔。每个元素由一个类型和一个标识符表示的参数组成。特别地,
参数类型... 标识符这样的参数被称为可变参数—— 可变参数见 Java 面向对象编程(基础)
方法体是实际要执行的代码块。方法体一般用 return 作为方法的结束。
使用 成员方法,能提高代码的复用性。而且能把实现的细节封装起来,供其他用户调用。
1 | class Cat{ |
- 方法写好后,不去调用就不会输出
- 先创建对象,然后调用方法即可
下面,展示一个含有成员方法的代码:
1 | public class Code6_2{ |
方法的调用机制
以前文代码为例:
1 | ... |
- 当程序执行到方法时,在 栈 中开辟一个新的 栈空间。该空间里储存
n1 = 15n2 = 135,之后计算并储存结果res = 150 - 当方法执行完毕,或执行到
return语句时,就会返回 - 把 新栈空间 中的
res = 150返回 main栈 中调用方法的地方 - 返回后,继续执行该方法的后续代码
使用细节
访问修饰符:作用是控制方法的使用范围。
- 不写(默认访问控制范围)
- public:公共
- protected:受保护
- private:私有
—— 访问修饰符见 Java 面向对象编程(中级)
返回数据类型:
- 一个方法最多有一个返回值。要返回多个结果可以使用 数组。
- 返回类型为任意类型。包括 基本数据类型 和 引用数据类型。
- 如果方法要求有返回数据类型,则方法体中最后的执行语句必为
return 值,且返回类型必须和 return 的值一致。 - 如果 返回数据类型 为
void,则可以不写return语句
方法名:
- 遵循驼峰命名法,最好见名知意,表达出该功能的意思。
参数列表(形参列表):
- 一个方法可以有 0 个参数,也可以有多个参数。参数间用
,间隔。 - 参数类型可以为任意类型,包含 基本类型 和 引用类型。
- 调用带参数的方法时,一定对应着 参数列表 传入 相同类型 或 兼容类型 的参数。
- 方法定义时的参数称为 形式参数 ,简称 形参;方法调用时的参数(传入的参数)称为 实际参数,简称 实参。实参 与 形参 的类型、个数、顺序必须一致。
- 一个方法可以有 0 个参数,也可以有多个参数。参数间用
方法体:
- 写完成功能的具体语句。方法中不能再定义方法。即:方法不能嵌套定义。
调用细节:
同一个类中的方法调用,可以直接调用。
跨类的方法调用,需要创建新对象,然后再调用方法。
1 | class C1{ |
成员方法传参机制
Java 语言对对象采用的是 值传递,方法得到的总是那个传入对象的副本。
方法不能修改基本数据类型的参数。基本数据类型传递的是一个值,形参不影响实参。
方法可以改变对象参数的状态。
引用类型传递的是一个地址,形参和实参指向一处,两者总会相关。
但改变那个形参地址指向的场合,实参的指向不会改变。
方法递归调用
递归:即方法自己调用自己,每次调用时传入不同变量。递归有助于编程者解决复杂问题,同时可以让代码变得简洁。
下面,示范一个斐波那契数列方法
1 | class T{ |
使用细节
- 执行一个方法时,就创建一个新的受保护的独立 栈空间。
- 方法的局部变量是独立的,不会相互影响。
- 如果方法中使用的是引用变量,就会共享数据。因为 6 面向对象编程(基础)
- 递归必须向退出递归的条件逼近,否则就是无限递归,会提示
StackOverflowError“死龟” - 当一个方法执行完毕,或遇到
return就会返回。遵守谁调用就返回给谁。同时当方法执行完毕或返回时,该方法也执行完毕。
方法重载
方法重载(Overload):Java 中允许同一类中,多个同名方法的存在,但要求 形参列表 不一致。
这样,减轻了起名和记名的麻烦。
使用细节:
- 方法名:必须相同
- 形参列表:必须不同(参数的类型、个数、顺序,这其中至少一个不同)
- 返回值:无要求
签名:
由于重载的存在,要完整的描述一个方法,要指定方法名及参数类型。这叫做方法的签名。
如:
1 | public void act() {} |
两个方法的签名分别是:act() 和 act(int n)
可变参数
Java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
语法:访问修饰符 返回类型 方法名(数据类型... 形参名){代码块;}
1 | public void m(int... n){ |
使用细节
可变参数 的实参可以是 0 个,也可以是 任意多 个。
可变参数 的实参可以是数组
可变参数 本质就是数组
因此,出现:
1
2public void met(int... n){ //这个方法与下面的方法不能构成重载
}的场合,不能有方法:
1
2public void met(int[] n){ //这个方法与上面的方法不能构成重载
}可变参数 和 普通参数 可以一起放在形参列表,但必须保证 可变参数 在最后
1
public void m(double dou, int... n) {}
一个形参列表最多出现 一个 可变参数。
作用域
- 在 Java 编程中,主要的变量就是 属性(成员变量)和 局部变量。
- 我们说的 局部变量 一般是指在成员方法中定义的变量。
- 作用域的分类
- 全局变量:也就是 属性,作用域为整个类体
- 局部变量:除了属性外的其他变量。作用域为定义它的代码块中
- 全局变量(属性)可以不赋值直接使用,那个场合有默认值。局部变量必须赋值使用
使用细节
属性 和 局部变量 可以重名,访问时遵循就近原则
在同一作用域中,两个局部变量不能重名
属性 的生命周期较长。其伴随对象的创建而创建,伴随对象的销毁而销毁。
局部变量 生命周期较短。其伴随代码块的执行而创建,伴随代码块的结束而销毁。
全局变量/属性 可以被本类使用,也可以被其他类(通过对象)使用。
局部变量 只能被本类的对应方法中调用
全局变量/属性 可以加 修饰符
局部变量 不能加 修饰符
构造方法、构造器
构造方法又叫构造器(constructor),是类的一种特殊的方法。它的主要作用是完成对新对象的初始化。
语法:[修饰符] 方法名(形参列表){方法体}
- 构造器的修饰符可以是默认。也可以是别的
- 参数列表 规则同 成员方法
以下示范一个构造器:
1 | class T{ |
使用细节
构造器本质也是方法。所以,可以 构造器重载。
构造器名 和 类名 相同
构造器无返回值
构造器是完成对象的初始化,而不是创建
创建对象时,系统自动调用构造器
如果程序员没有定义构造器,系统会自动给类生成一个无参构造器(默认构造器)
一旦定义了自己的构造器,就不能用无参构造器了。除非显式的定义一个无参构造器
流程分析
1 | Person p1 = new Person("Amy", 10); |
加载 类信息(方法区)
在 堆 中开辟空间(地址)
完成对象初始化
首先默认初始化。
age = 0; name = null之后显式初始化。
age = 20; name = null其中,显式初始化和代码块初始化按编写的先后顺序依次进行。
之后构造器的初始化。
age = 10; name = "Amy"
把对象在 堆 中的 地址,返回给
p1
this 关键字
JVM 会给每个对象分配 this 代表当前对象。
相当于在 堆 中,this 指向自己(对象)
在类定义的方法中,Java 会自动用 this 关键字把所有变量和方法引用结合在一起。
遇到有同名的局部变量的场合,需要程序员加入 this 关键字进行区分。不加入 this 关键字的场合,Java 遵循就近原则。
1 | class Example{ |
上面这个类的 act() 方法实际有 2 个参数。对其调用:
1 | Example e = new Exmaple(); |
可见,出现在方法名前的参数 e,以及出现在方法名后的括号中的参数 100
出现在方法名前的参数被称为 隐式参数(也称为 方法调用的 目标 或 接收者)
出现在方法名后的参数被称为 显式参数,就是所谓的实参
在每一个方法中,用 this 指代隐式参数。
1 | public void act(int n) { |
此时,再以相同方式调用方法:
1 | e.act(100); // <———— 相当于 e.n = 100; |
使用方法
this关键字可以用来访问本类的属性、方法、构造器this用于区分当前类的 属性 和 局部变量访问本类中成员方法的语法:
this.方法名访问构造器的语法:
this(参数列表);注意:只能在构造器中访问另一个构造器。而且,如果有这个语法,必须放置在第一条语句。
this不能在类定义的 外部 使用,只能在类定义的 方法中 使用
附录
迷宫游戏代码
1 | /** |
八皇后代码
1 | import java.util.Scanner; |







