2.面向对象编程——static、package包、import、封装性、继承性的前半部分

一、static关键字

static,译为静态。
一个类的成员包括:变量、方法、构造方法、代码块和内部类,static可以修饰除了构造方法外的所有成员。
使用static修饰的成员称为静态成员,是属于某个类的。而不使用static修饰的成员为实例成员,是属于该类的每个对象的。

1 static变量

static修饰的成员变量为静态变量,也叫类变量。类变量的声明周期和类相同,在整个应用程序执行期间都有效。

静态变量的特点
为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时显示初始化。
对于该类的所有对象来说,static成员变量只有一份,被该类所有对象共享。
一般用“类名.类属性/方法”来调用。
在static方法中不可直接访问非static的成员。

静态变量和非静态变量的区别

  1. 份数不同:静态变量只有一份,为该类的所有实例对象共享。非静态变量每个实例对象都有一份。
  2. 存储的位置不同:静态变量存储在方法区(也叫元空间)内,非静态变量存储在堆内存中。
  3. 分配内存空间的时间不同:静态变量在类第一次被加载时分配空间,非静态变量在对象创建时分配空间。
  4. 生命周期不同:静态变量声明周期与类相等,非静态变量声明周期与所属对象相等。
  5. 调用方式不同:静态变量可以通过“类名.变量名”调用,也可以通过“对象名.变量名”调用。(推荐使用“类名.变量名”,因为静态变量只有一份,为所有该类创建的对象共享。)而非静态变量只能通过“对象名.变量名”调用。

2 static方法

static方法的作用
访问static变量和static方法
static方法的调用方式
可以使用“类名.方法名()”调用,也可以使用“对象名.方法名()”调用。但是推荐使用第一种方式,因为static方法不依赖于对象,所以调用时可能并没有创建对象。
不可以
静态方法不可以访问非静态变量
静态方法不可以访问非静态方法
静态方法不可以使用this关键字

个人理解:因为在静态方法不依赖于对象,所以调用静态方法时也许并没有创建对象,非静态变量和方法没有被分配空间,更没有this被创建。

可以
非静态方法可以访问静态变量
非静态方法可以访问静态方法

个人理解:在调用非静态方法时,必然已经创建对象,而静态变量和方法在创建对象前已经存在,所以可以访问

3 static代码块

代码块分为局部代码块,成员代码块和static代码块。

3.1 局部代码块

位置:方法中
数量:多个
执行顺序:依次执行
局部代码块中定义的变量只作用与当前代码块

3.2 成员代码块

位置:类中
数量:多个
执行顺序:依次执行
执行时间:每次创建对象时都会执行,先执行代码块再执行构造方法。
作用:可以将各个构造方法中公共的代码提取到代码块中,实际开发中使用较少。
匿名内部类不能提供构造方法,此时初始化操作放到代码块中

3.3 static代码块

位置:类中
数量:多个
执行顺序:依次执行
执行时间:类被加载时执行,只执行一次。
作用: 给静态变量赋予初始值。实际开发中应用较多,一般用于执行一些全局性初始化操作,例如创建工厂,加载数据库初始信息。

二、package包

包机制是Java中管理类的重要手段。开发中,我们会遇到大量同名的类,通过包可以很容易饿解决类重名的问题。另外,包还和访问权限有着密切的关系。

1.如何定义包

  1. 包名一律小写。
  2. 包名:域名倒着写即可,再加上模块名,便于内部管理类。
  3. 看起来是包含关系的包实际上是两个完全独立的包,只是逻辑上是包含的关系。例如com.gao和com.gao.car

另外如何优雅的给包命名呢???
2.面向对象编程——static、package包、import、封装性、继承性的前半部分
知乎原网址:如何优雅的给个人项目的包命名

三、import导入

  1. 默认是当前包下的类和接口
  2. Java会默认导入java.lang包下的所有类,所以我们可以直接使用。
  3. 可以使用通配符,例如 import java.util.*
  4. 如果导入两个同名的类,只能用包名+类名来显示调用相关类:java.util.Date date = new java.util.Date();

在JDK1.5以后添加了静态导入功能,作用是可以导入指定类的静态属性或静态方法,这样就可以直接使用静态属性和静态方法。例如:import java.lang.Math.PI;

四、面向对象的三大特征之一:封装性

封装(encapsulation)是面向对象三大特征之一。合理的封装让外部调用更加方便,同时,对于实现着来说也更加容易修正和改版代码。

1.引入封装

举个栗子:我要看电视,只需要按一下开关和换台就可以了。不必了解电视机内部的复杂结构。制造厂家为了方便我们使用电视,把复杂的内部细节都封装起来,之暴露给我们简单的接口。

封装就是吧对象的属性和操作结合为一个独立的整体,并尽可能的隐藏对象的内部细节。

程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉。低耦合是仅暴露少量的方法给外部使用,尽量方便外部调用。

封装的优点

  • 提高代码安全性。
  • 提高代码复用性。
  • 高内聚:封装细节,便于修改内部代码,提高可维护性。
  • 低耦合:简化外部调用,便于调用者使用,便于拓展和写作。

2.权限修饰符

2.面向对象编程——static、package包、import、封装性、继承性的前半部分

  1. private 只有自己类能够访问
  2. defaule 默认的权限修饰符,只有同一个包的类可以访问
  3. protected 可以被同一个包和其他包中的子类访问
  4. public 可以被该项目所有包的所有类访问

类的成员处理

  • 一般使用private访问权限(高内聚)
  • 提供相应的set/get方法访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值取值操作。(布尔类型变量的get方法以is开头)
  • 一些用于本类的辅助性方法用private修饰,希望其他类调用的用public修饰。

类的处理

  • 类只能使用public和默认修饰

五、面向对象的三大特征之二:继承性

继承(inheritance)是面向对象编程三大特征之一,它让我们更加容易实现对已有类的拓展、更加容易实现对现实世界的建模。

1.继承的作用

继承让我们更加容易实现类的拓展。例如,我们定义了动物类,再定义狗类只需要拓展动物类即可。实现了代码的重用,不必重复造轮子。

继承的要点

  1. 父类也称为超类、基类。子类也称为派生类等。
  2. Java中只有单继承。(多继承会使继承链过于复杂,系统难于维护)
  3. 子类继承父类,可以得到父类除了构造方法外的的全部属性和方法,但不一定可以直接访问,比如父类的私有属性和方法。
  4. 一个类如果没有使用extends继承父类,则它的父类是:java.lang.Object

2.方法重写

当父类的方法无法满足子类的需求时,子类可以通过方法重写来满足需求。

方法重载和方法重写的区别
方法重载和方法重写是面向对象中的两个重要概念,两个概念实际上并没有什么关联,但是因为两者都是关于方法的,比较容易引起混淆。我认为两者的区别可以从总体和细分两个方面说明。
总体来说,最主要的区别就是两者解决的问题不同,也就是作用不同。
方法重载英文为overload,使用的位置是在当前类中,作用是为类的一种行为提供多种实现方式并提高可读性。
方法重写英文为override,使用的位置是在子类与父类之间,作用是当父类的方法无法满足子类需求时,通过方法重写来满足需求。
细分来说,一个方法的声明从左到右分别为修饰符、返回值类型、方法名、参数列表、返回的异常类型等。
方法重载与修饰符、返回值类型和返回的异常类型无关,但是方法名必须相同,参数列表必须不同。
而方法重写的方法名和参数列表必须相同,修饰符权限必须大于或等于父类方法的修饰符,返回值类型和返回的异常类型必须小于或等于父类方法的返回值类型和返回的异常类型。
我们常用的方法重载有:构造方法的重载,println()方法的重载。
常用的方法重写有:Object类的toString()、equals()和hashCode()等都可被子类重写。
另外,如果方法被final修饰或者为静态方法,则无法重写。

六、声明

文档来源于“北京尚学堂”,本人只进行了知识点的整理,目的在方便自己。
另外如果有朋友想学习java、python、前端、大数据等知识欢迎来到“北京尚学堂”咨询

北京尚学堂官网:北京尚学堂