Java面向对象(上)

​ 在开始学习Java之前就知道Java是一种面向对象的编程语言,但是对于什么是面向对象却没有明确的了解,在学习了本章之后,对于面向对象有了初步的了解,本篇文章梳理了该章节的重点知识。

​ 如果感兴趣的话就继续看下去吧!

面向对象的概念

面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象)概念的程序编程典范,同时也是一种程序开发的抽象方针。

​ 简单概括,面向对象开发是相对于结构化开发而言的,这种思想的产生来源于自然界,对于存在于自然界中的所有物质我们都能够将他归类,例如人类、动物类、食物类等等,而对于这些类我们都能够概括定义出他的属性和功能。针对程序设计,我们可以把程序看作是各种对象的集合。

程序 = 自然界

对象 = 人类、动物类……

面向对象的特点

  • 封装性:核心,将对象的属性和行为封装成类,实现对用户隐藏细节
  • 继承性:不同类之间关系的一种,目前还不太明确:(
  • 多态性:以统一的风格编写程序

1. 类与对象

1.1 类与对象的关系

类是一种抽象的概念模板,对象是类在程序中的实例

静态部分(属性) = 成员变量

动态部分(功能) = 成员方法

​ 例如:男人、女人是类(class),具体的某个人就是该类的对象(object)

1.2 Java中的类

​ 类是对象的一个模板,描述的是一类对象的行为和状态。一个类中可以包含一下变量:

  • 局部变量

  • 成员变量

  • 类变量(静态变量)

    1.2.1 构造方法

​ 每个类至少要有一个构造方法,构造方法的名称与类同名。如果没有显式的定义构造方法,那么系统就会提供默认构造方法。

注意:

1.构造方法没有返回值类型,不能使用return返回一个值

构造方法中可能出现的错误

​ 当定义有参数的构造方法时,系统就不会再提供默认构造方法,可能会导致出错。

构造方法的重载

​ 定义参数列表不同的构造方法,在实例化对象时,系统会自动调用参数列表匹配的构造方法

1.2.2 类的封装

​ 类的封装能够隐藏类的实现细节,主要方法

通过private修饰私有属性,通过public公有化属性访问器(setXXX && get XXX)

1.3 Java中的对象

​ 对象是根据类创建的,创建对象需要以下三步:

  • 声明对象:包括对象名(引用变量)和对象类型
  • 实例化:使用new关键字创建对象,开辟独立的堆内存空间
  • 初始化:使用new创建对象时,会调用构造方法初始化对象

2. this关键词

​ 为了避免冲突,this表示当前的对象,主要有以下三种用法:

2.1 this调用类的属性

​ 当成员变量与局部变量重名时,使用this明确调用类的成员变量

2.2 this调用类的成员方法

​ 用与访问成员变量相同的方式访问成员方法

2.3 this调用类的构造方法

​ 调用方法:使用this[实参列表]调通其他的构造方法

注意:

1.在构造方法中调用构造方法(一层套娃)只能出现一次,并且this()语句必须位于该构造方法的第一句。

2.需要留一个构造方法作为出口,至少存在一个构造方法不使用this调用其他构造方法(通常将无参数的构造方法作为出口)

3. Java中的垃圾回收机制

​ Java会自动回收堆内存中的垃圾空间,除此之外,还可以人为调用System. gc()方法建议需虚拟机立即执行垃圾回收,但是否执行并不能确定。

​ Stop-the-World是由于要执行GC操作而停止整个程序的执行,任何一个GC操作都会发生,此时所有的线程都会处于等待状态,对GC的优化就是减少Stop-the-World的发生次数,使系统具有高吞吐、低停顿的特点。

Java中的自动回收机制参考文章

4. static关键词

4.1 静态变量

静态变量:使用static修饰的关键词修饰的成员变量,能够被类的所有对象所共同访问,可以直接通过类名来访问

实例变量:未使用static修饰的成员变量,只能够通过引用变量访问

  • 注意:static在修饰变量的时候只能够修饰成员变量,不能够修饰方法中的局部变量

4.2 静态方法

​ 静态方法的调用不需要创建类的实例,可以直接通过类名调用

  • 注意:静态方法只能够访问类的静态成员,不能够访问实例成员。原因:static修饰的成员属于类,而未被static修饰的成员都是属于对象的

4.3 代码块

​ 使用{}括起来的一段代码,可以分为普通代码块、构造代码块、静态代码块、同步代码块

4.3.1 普通代码块

​ 用在方法名后或方法体内,使用最多的、最普通的代码块

4.3.2 构造代码块

​ 直接定义在类中,只有一对花括号,构造代码块在构造方法之前执行,同样是在创建对象时被自动调用。

​ 可用于初始化成员变量。

多个构造代码都需要初始化成员变量,可将重复的部分提取,构成构造代码块

4.3.3 静态代码块

​ 使用static修饰,最早执行的代码块,只会执行一次。

4.3.4 单例模式

​ 单例模式是一种设计模式。单例类只创建自己唯一的实例,只给全局提供一个直接访问点。

主要解决:一个全局使用的类频繁地创建与销毁。

何时使用:当您想控制实例数目,节省系统资源的时候。

5. 内部类

​ 在类中定义的类,他所在的类称为外部类。使用内部类比那些的代码的可读性很差。

1.内部类和外部类是两个独立的类。

2.内部类可以看成是外部类的一个成员,故内部类可以访问外部类的任何其他成员。

3.内部类可被static修饰为静态,外部类只能用public或默认的访问权限

5.1 成员内部类

​ 向外:通过OuterClass.this能直接访问外部类的引用

​ 向内:外部类只能通过内部类的引用来访问内部类的成员

  • 注意:成员内部类不能定义静态变量、静态方法和静态内部量。
  • 只有先创建了外部类,才能够创建内部类

5.2 静态内部类

​ 可以有实例成员和静态成员。

向外:直接访问外部类的静态成员;

​ 必须通过外部类的对象访问外部类的实例成员

向内:访问静态内部类成员,不用创建外部类对象,只需创建内部类对象

5.3 方法内部类

​ 成员方法中定义的类,作用域为定义它的代码块,只能在该成员方法内实例化。

向外:也能够访问外部类成员

5.4 匿名内部类

​ 没有名字的内部类,属于局部内部类的一种。匿名内部类总是可以用其他的更加规范的书写顺序替换,它会使得代码的可读性变差,并不推荐使用。匿名内部类的另一个缺点就是由于他没有名字,所以不能够复用。下面演示匿名内部类的一种使用场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class TestAnnoymousInner {
public static void main(String[] args) {
/*Action1 a1 = new Action1();
a1.say();*/

//通过抽象类来实现接口
new Action(){
public void say() {
System.out.println("通过匿名内部类来实现接口");
}
}.say();
}
}

interface Action {
//创建一个抽象方法
void say();
}
/*

//正常情况下,我们需要创建一个类来实现接口
class Action1 implements Action {
public void say() {
System.out.println("正常创建类来实现接口。");
}
}
*/

上述程序的输出结果是:“通过匿名内部类来实现接口”

5.5 内部类的总结

  1. 怎样初始化内部类?

    OutClass.InnerClass innerclass = new OutClass().new InnerClass();

  2. 如何用内部类调用外部类的成员?
  3. 在使用内部类时需要注意什么?
  4. 内部类和外部类有什么关系?

内部类的使用会使得代码的阅读性变差,因此内部类在实际的开发中的使用不多,并不是我们需要掌握的终点,但是我们依然需要了解他的基本使用规则。