专栏:《Java面向对象程序设计》学习笔记
第四章 类与对象
4.1 编程语言的几个发展阶段
4.1.1 面向机器语言
机器语言、汇编语言为低级语言
4.1.2 面向过程语言
过程语言为高级语言
面向过程语言的核心是编写解决某个问题的代码块
4.1.3 面向对象语言
封装性
-
将数据和对数据的操作封装在一起
-
(可以抽象出类和实例的概念)
继承性
- 子类可以继承父类的属性和功能
- 子类既继承了父类所具有的数据和数据上的操作,同时又可以增添子类独有的数据和数据上的操作。
多态性
操作名称的多态
- 有多个操作具有相同的名字,但这些操作所接收的消息类型必须不同(可以向操作传递不同消息,以便让对象根据相应的消息来产生一定的行为)。
继承有关的多态
- 同一个操作被不同类型对象调用时可能产生不同的行为
4.2 类
类是组成 Java 程序的基本要素。
类的定义包括两部分:类声明和类体。
class 是关键字,用来定义类。 "class 类名”是类的声明部分,类名必须是合法的 Java 标识符。两个大括号以及之间的内容是类体(一个类的类体由两部分组成,即变量的声明和方法的定义)。
4.2.3 成员变量和局部变量
成员变量:在变量声明部分声明的变量;
局部变量:在方法体中声明的变量和方法的参数
变量的有效范围
- 成员变量在整个类内都有效,局部变量只在声明它的方法内有效。
- 方法参数在整个方法内有效,方法内的局部变量从声明它的位置之后开始有效。
- 成员变量的有效性与它在类体中书写的先后位置无关
实例变量与类变量
- 成员变量分为实例变量和类变量。
- 在声明成员变量时,用关键字 static 给予修饰的变量称为类变量,否则称为实例变量(类变量也称为 static 变量,静态变量)
- static 需放在变量的类型的前面。
成员变量的隐藏(个人理解为临时覆盖了原成员变量)
- 如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。
4.2.4 方法
一个类的类体由两部分组成,即变量的声明和方法的定义。
方法的定义包括方法声明和方法体。
方法声明
- 最基本的方法声明包括方法名和方法的返回类型。
- 当一个方法不需要返回数据时,返回类型必须是 void 。
- 多个参数用逗号隔开。
4.2.5 方法重载
Java 中存在两种多态,即重载(overload)和重写( override )。
方法重载是多态性的一种。
所谓功能多态性,是指可以向功能传递不同的消息,以便让对象根据相应的消息来产生相应的行为。对象的功能通过类中的方法来体现,那么功能的多态性就是方法的重载。
方法重载的意思是,一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同,即或者是参数的个数不同,或者是参数的类型不同。
如果两个方法的名字相同,即使类型不同,也必须保证参数不同。
(反正不同就是了)
4.2.6 构造方法
构造方法是一种特殊方法
- 它的名字必须与它所在的类的名字完全相同。
- 没有类型。
- 构造方法也可以重载。
- 用类创建对象时,使用构造方法。
(名字和类名一样的肯定是构造方法啦)
4.2.7 类方法和实例方法
成员变量可分为实例变量和类变量,同样,类中的方法也可分为实例方法和类方法。
在声明方法时:
-
实例方法:方法类型前面不加关键字 static 修饰
-
类方法(静态方法):方法类型前面加关键字 static 修饰
需要注意的是, static需放在方法的类型的前面。
4.2.8 几个值得注意的问题
成员变量的操作
-
对成员变量的操作只能放在方法中。
-
方法可以对成员变量和该方法体中声明的局部变量进行操作。
-
在声明类的成员变量时可以同时赋予初值。
(其实就是,声明时赋值 or 声明后在方法里赋值)
方法对变量的操作
- 实例方法既能对类变量操作也能对实例变量操作。
- 类方法只能对类变量进行操作。
调用方法:
-
一个类中的方法可以互相调用,实例方法可以调用该类中的其他方法。
-
类中的类方法只能调用该类的类方法,不能调用实例方法。
4.3 对象
用类声明的变量被称为对象
在用类声明对象后,还必须创建对象。
用一个类创建一个对象 == 给这个类的一个实例
4.3.1 构造方法
当程序用类创建对象时需使用它的构造方法。
- 默认构造方法:如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句(啥也没有)。
- 自定义构造方法:如果类中定义了一个或多个构造方法,那么 Java 不提供默认的构造方法(自定义了就不用默认的了)。
- 构造方法没有类型(有类型的都不是构造方法)。
4.3.2 创建对象
创建一个对象包括对象的声明和为对象分配变量两个步骤。
对象的声明:类的名字+对象名字;
为对象分配变量:使用 new 运算符和类的构造方法为声明的对象分配变量。
4.3.3 使用对象
抽象的目的是产生类,而类的目的是创建具有属性和行为的对象。
对象不仅可以操作自己的变量改变状态,而且可以调用类中的方法产生一定的行为。
通过使用运算符“,”,对象可以实现对自己的变量的访问和方法的调用。
体现封装
- 当对象调用方法时,方法中出现的成员变量就是指分配给该对象的变量。
- 类中的方法可以操作成员变量。
需要注意的是,局部变量声明时如果没有初始化,就没有默认值,因此在使用局变量之前,要保证该局部变量有值。
在编写程序时尽量避免使用匿名对象去访问自己的变量,以免引起混乱。
4.3.4 对象的引用和实体
类是体现封装的一种数据类型(封装着数据和对数据的操作)。
类所声明的变量被称为对象。
对象(变量)负责存放引用,以确保对象可以操作分配给该对象的变量以及调用类中的方法。
分配给对象的变量被习惯地称作对象的实体。
-
避免使用空对象,程序运行时会触发 java. lang.NullPointerException 异常。
-
一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量(实体)。
比如 p1 = p2 ,即把 p2 中的引用赋给了 p1 ,那么 p1 和 p2 本质上就是一样的了。
4.4 参数传值
当方法被调用时,如果方法有参数,参数必须实例化,即参数变量必须有具体的值。
如果方法改变参数的值,不会影响向参数“传值"的变量的值。(就是不会影响原来的值)。
4.4.1 基本数据类型参数的传值
存放的是值。
向该参数传递的值的级别不可以高于该参数的级别。
4.4.2 引用类型参数的传值
存放的是引用(内存地址)。
对于两个同类型的引用型变量,如果具有同样的引用,就会用同样的实体,因此,如果改变参数变量所引用的实体,就会导致原变量的实体发生同样的变化。但是,改变参数中存放的“引用”不会影响向其传值的变量中存放的“引用”,反之亦然。
(这里主要是要搞清“引用”的实际含义,那么一切就都明朗了)
4.4.3 可变参数
可变参数是指在声明方法时不给出参数列表中从某项直至最后一项参数的名字和个数,但这些参数的类型必须相同。
可变参数使用“···"表示若干个参数,这些参数的类型必须相同,最后一个参数必须是参数列表中的最后一个参数。
(这个主要用于传值不固定个数,但是类型都相同的情况)
4.4.4 有理数的类封装
面向对象编程的核心思想之一就是将数据和对数据的操作封装在一起。
即通过抽象从具体的实例中抽取共同的性质形成类的概念,再由类创建具体的对象,然后通过对象调用方法产生行为,以达到程序所要实现的目的。
分数运算(挺经典的题目,强烈建议自己敲一遍,当然书上的做法并不是最简的)。
4.5 对象的组合
对象可以由几个对象组合而成。
小结一下
类体的定义包括成员变量的定义和方法的定义,并且成员变量又分为实例变量和类变量,用 static 修饰的变量是类变量。
除构造方法外,其他的方法可分为实例方法或类方法。
在方法声明中用关键字 static 修饰的方法称为类方法或静态方法,不用 static 修饰的方法称为实例方法。
一个类中的方法可以互相调用:实例方法可以调用该类中的实例方法或类方法;类方法只能调用该类的类方法,不能调用实例方法。
4.6 static 关键字
4.6.1 实例变量和类变量的区别
一个类通过使用 new 运算符可以创建多个不同的对象,这些对象将被分配不同的内存空间。
如果类中有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量。也就是说,对象共享类变量。
类变量是和该类创建的所有对象相关联的变量,改变其中一个对象的这个类变量就同时改变了其他对象的这个类变量。
因此,类变量不仅可以通过某个对象访问,也可以直接通过类名访问。
实例变量仅仅是和相应的对象关联的变量。
也就是说,不同对象的实例变量互不相同,即分配不同的内存空间,改变其中一个对象的实例变量不会影响其他对象的这个实例变量。实例变量可以通过对象访问,不能使用类名访问。
写了个简单的例子 → 静态内部类的访问方法(static/无static)
用 static 修饰的是类方法,否则为实例方法
实例方法可以被类创建的任何对象调用执行
类方法不仅可以被类创建的任何对象调用执行,也可以直接通过类名调用。
允许通过类名直接调用类方法,而实例方法不能通过类名调用。在 Java 语言中,类中的类方法不可以操作实例变量,也不可以调用实例方法。
如果一个方法不需要操作实例成员变量就可以实现某种功能,就可以考虑将这样的方法声明为类方法。这样做的好处是避免创建对象浪费内存。
4.7 this 关键字
this 是 Java 的一个关键字,表示某个对象。
this 可以出现在实例方法和构造方法中,但不可以出现在类方法中。
4.7.1 在构造方法中使用 this
this 关键字出现在类的构造方法中时,代表使用该构造方法所创建的对象。
可省略this。
4.7.2 在实例方法中使用 this
实例方法只能通过对象来调用,不能用类名来调用。
当 this 关键字出现在实例方法中时,代表正在调用该方法的当前对象。
实例方法可以操作类的成员变量。
通常情况下可以省略实例成员变量名字前面的“ this. ”以及 static 变量前面的“类名.”。
当实例成员变量的名字和局部变量的名字相同时,成员变量前面的 "this. ”或“类名.”不可以省略。
类的实例方法可以调用类的其他方法。
一个实例方法调用另一个方法时可以省略方法名字前面的 "this. ”或“类名。
this 不能出现在类方法
4.8 包
了解即可
4.9 import 语句
自行学习
4.10 访问权限
范围 | private | default | protected | public | |
---|---|---|---|---|---|
1 | 同一包中的同一类 | ✔ | ✔ | ✔ | ✔ |
2 | 同一包中的不同类 | ✔ | ✔ | ✔ | |
3 | 不同包中的子类 | ✔ | ✔ | ||
4 | 不同包中的非子类 | ✔ |
四种访问权限范围的大小从小到大:private < default(默认访问权限) < protected < public
在子类中访问父类中的变量时需要用super
4.11 基本数据类型的类封装
基本数据类型的类封装,这块看一下就知道的。
4.11.4 自动装箱与拆箱
基本类型数据类型的自动装箱与拆箱:基本类型数据和相应的对象之间相互自动转换。
自动装箱:允许把一个基本数据类型的值直接赋给基本数据类型相对应的类的实例。
lnteger number = 100;
//或
int m = 100;
lnteger number = m;
//装箱
lnteger number = new lnteger(m);
自动拆箱
- 允许把基本数据类型相对应的类的实例直接赋给相应的基本数据类型变量。
- 或把基本数据类型相对应的类的实例当作相应的基本数据类型来使用。
int x = number + number;
//拆箱
int x = number.intValue() + number.intValue();
自动装箱与拆箱仅仅是形式上的方便,在性能上并没有提高,而且装箱时必须保证类型一致。
Float c = 12;//这样是错的,因为数据类型不一致
Float c = 12f;
//装箱
Float c=new Float(12);//这样总是正确的
不一定非要使用这种形式,结合自己的编程习惯。
4.12 反编译器和文件生成器
跳过
4.13 jar 文件
跳过
4.14 var 声明局部变量
JDK10才支持,且用的不多,跳过