5.1 类与对象
-
类:是组成 Java 程序的基本要素,是一类对象的原型
-
是一种抽象的数据类型,对某一类事物整体描述/定义,不代表某一具体事物
-
类的构成:类 = 类头+类成员
-
类成员构成:类成员 = 字段名(field)+方法(method)
- 字段(field):类的属性,通过变量表示。字段又称域、域变量、属性、成员变量等
- 方法(method):类的功能和操作,通过函数表示
-
例如:
class Person{ String name; int age; void sayHello(){ System.out.println("Hello! My name is "+ name); } }
-
-
对象:面向对象的语言的基本概念
-
对象在计算机世界中表示的是一个可标识的存储区域
-
创建对象:使用 new 关键字
- 创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认初始化和对类中的构造器的调用
- 类的构造器:也称构造方法,在进行创建对象的时候必须调用(在方法中会重点讲)
- 创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认初始化和对类中的构造器的调用
-
访问对象的字段或方法,需要使用运算符
.
-
例如:
Person p = new Person(); System.out.println(p.name); p.sayHello();
-
使用
.
访问的好处:封装性、安全性
-
-
-
类与对象的关系
- 类是对象的抽象(模板)
- 对象是类的实例
- 注:类和对象有时都称为“对象”,为了明确区分,后者通常称为“对象实例”
5.2 作用域
-
类变量
- 类级变量又称全局级变量或静态变量,需要使用 static 关键字修饰。类级变量在类定义后就已经存在,占用内存空间,可以通过类名来访问,不需要实例化。
- 从属:类
-
实例变量
- 对象实例级变量就是成员变量,实例化后才会分配内存空间,才能访问。如果不自行初始化,系统以默认值初始化。成员变量是定义在方法之外,类之内的。成员变量随着对象的创建而存在,随着对象的消失而消失。
- 数值类型默认为 0
- Boolean 默认为 False ¥
- 除了基本类型其他默认为 null
- 从属:对象
- 对象实例级变量就是成员变量,实例化后才会分配内存空间,才能访问。如果不自行初始化,系统以默认值初始化。成员变量是定义在方法之外,类之内的。成员变量随着对象的创建而存在,随着对象的消失而消失。
-
局部变量
- 方法级变量就是在方法内部定义的变量,就是局部变量。需要声明和初始化值。局部变量在调用了对应的方法时执行到了创建该变量的语句时存在,局部变量的作用域从它被声明的点开始,一旦出了自己的作用域马上从内存中消失。
- 从属:方法
-
例如:
public class HelloWorld {
static int a =1; //类变量
String string = "Hello"; //实例变量
public static void main(String[] args) {
String b = "World"; //局部变量
}
}
5.3 方法
5.3.1 认识方法
-
方法是语句的集合,在一起执行一个功能,是解决一类问题的步骤有序组合。包含在对象或者类里,在程序中被创建,在其他地方被引用
-
设计方法的原则:原子性(一个方法只完成一个功能¥)
- 有利于我们以后的发展
-
定义:Java 的方法是一段用来完成特定功能的代码片段
-
方法构成:方法 = 方法头+方法体
-
语法格式:
[修饰符] 返回值类型 方法名 (参数类型 参数名){ 方法体 [return 返回值;] }
修饰符:可选。定义该方法的访问类型,目的在于告诉编译器如何调用该方法
返回值类型:有些方法可能需要返回值,而返回值类型是方法返回值的数据类型;在没有返回值的情况下,返回值类型为 void(void:返回空值,是返回值为空的关键字)
方法名:方法的实际名称。方法名和参数列表共同构成方法签名。参数列表:方法的参数类型、顺序和参数的个数
方法体:包含具体的语句,定义该方法的功能
return:可选。如果有返回值,需要使用 return 关键字,return 还可以终止函数
-
-
方法的调用
-
调用方法:
对象名.方法名(实参列表)
-
Java 支持两种调用方法,依据是否有返回值来进行判断
- 当有返回值时,方法调用通常被当作一个值
- 如果返回值时 void,方法调用一定是一条语句
- 当有返回值时,方法调用通常被当作一个值
-
5.3.2 可变参数
-
可变参数也称不定项参数,从 JDK 1.5 开始支持的可传递同类型的可变参数
-
使用方法
- 在方法声明中,在指定参数类型后面加一个省略号
...
- 一个方法只能指定一个可变参数,而且必须位于最后一个参数,任何普通参数必须在它之前声明
- 在方法声明中,在指定参数类型后面加一个省略号
-
例如:
public void test(int ... i){ System.out.println(i) }
5.3.3 构造方法
-
构造方法(constructor):一种特殊的方法,用来初始化(new)该类的一个新对象
-
构造方法与类名相同,不写返回数据类型
-
例如:
Person(String n,int a){ name = n; age = a; }
-
-
一般情况下,类都有一个或多个构造方法
-
意义:
- 构造方法是 new 的本质
- 用于初始化对象的值
-
默认构造方法:如果没有定义任何构造方法,系统会自动产生一个构造方法
- 默认构造方法不带参数,并且方法体为空
-
快捷创建构造方法快捷键(IDEA):
Alt+Insert
5.3.4 this 的使用
-
在方法及构造方法中,使用 this 来访问本类的字段及方法
-
例如:方法 sayHelllo() 中使用 name 和 this.name 是相同的
void sayHello(){ System.out.println("Hello! My name is "+ name); }
void sayHello(){ System.out.println("Hello! My name is "+ this.name); }
-
-
使用 this 解决局部变量或参数变量与域变量同名的问题
-
例如:在构造方法中,经常这样使用
Person(int age,String name){ this.age = age; this.name = name; }
this.age 表示的是域变量,age 表示的是参数变量
-
-
在构造方法中,使用 this 调用另一个构造方法
-
例如:
Person(){ this(0,""); …… }
在构造方法中调用另一构造方法的调用语句必须放在第一句
-
5.3.5 递归
- 自己调用自己,通俗来讲 A 方法 调用 A 方法
- 用途:
- 可以使用一个简单程序来解决一些复杂问题
- 大大减少程序代码量
- 用有限语句来定义对象的无限集合
- 核心:
- 递归头:用于结束递归,防止陷入死循环
- 递归体:用于递归时执行的方法
5.3.6 方法重载
-
方法重载(overload):当存在多个方法有相同名字,为了使编译时能识别出来的一种操作
-
规则:
- 方法名称必须相同
- 参数列表必须不同,一者不同即可分辨
- 参数列表=方法的参数类型+参数顺序+参数个数
- 方法签名=方法名+参数列表
- 方法类型可以相同
- 仅仅返回类型不同,不构成方法重载
-
实现理论:方法名称相同时,编译器会根据方法的参数列表逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错
-
通过方法重载可以实现多态(polymorphism)
5.4 访问控制符
5.4.1 认识访问控制符
-
访问控制符也叫访问修饰符,可以修饰类、类的成员(变量、方法)
-
修饰符分为访问修饰符和其他修饰符
- 访问修饰符(access modifieds)例如:public、private 等
- 其他修饰符如:abstract 等
-
成员的访问控制符:在定义变量方法时使用访问控制符,也称为权限修饰符
-
成员的访问控制符的作用(可访问的范围)
同一个类中 同一个包中 不同包的子类 不同包的非子类 private yes 默认 yes yes protected yes yes yes public yes yes yes yes private:将某个类或者成员私有化,从而更好将信息进行封装和隐藏,一般用于封装
默认:在 Java 中就算自己不定义修饰符,Java 也会默认生成
protected:特殊点是不管子类是否位于本包,其子类都可以调用继承的 protected 方法或成员
-
-
类的访问控制符:在定义类时,也可以使用访问控制符
- 一般在类中的访问控制符是 public 或者默认
- public:该类可以被其他类访问
- 默认:该类只能被同包的类访问
- 一般在类中的访问控制符是 public 或者默认
-
其他修饰符:也称非访问控制符
基本含义 修饰类 修饰方法 修饰局部变量 static 静态的、非实例的、类的 yes yes final 最终的、不可改变的 yes yes yes abstract 抽象的、不可实例化的 yes yes
5.4.2 static 关键字
-
static 所定义的最本质的特点:属于类,不属于任何一个对象实例
- 不保存在某个对象实例的内存空间中,保存在类的内存区域的公告存储单元
-
在变量中,使用 static 修饰的变量称为静态变量
-
例如:
private static int age; //静态变量 age private double score; //非静态变量 score
-
作用:
- 可以通过类名或实例对象来直接调用静态属性
- 非静态属性不能通过类名调用,只能通过实例对象调用
- 在一定意义上,可以用来表示全局变量
- 可以通过类名或实例对象来直接调用静态属性
-
-
在方法中,使用 static 修饰的方法属于类的静态方法,又称类方法
-
与此相对,没有 static 的方法称为实例方法
-
例如:
//非静态方法 public void go(){ …… } //静态方法 public static void main(String[] args){ …… }
-
说明:因为 static 方法是属于整个类的,所以不能操作和处理某个对象的成员变量,只能处理属于整个类的成员变量,即 static 方法只能处理本类的 stactic 成员或者调用 static 方法
- 非静态方法可以直接调用静态方法,静态方法不能调用非静态方法
- static 方法不能访问实例变量,不能使用 this 和 super
- 调用时,推荐使用类名直接调用,也可以使用对象名调用
-
-
在块中,静态代码块
-
例如:
public class Person{ //匿名代码块 {……} //静态代码块 static {……} }
匿名代码块一般不使用,可以用来赋予初始值。在创建对象时创建,生成于构造器之前,程序执行时不会主动调用
静态代码块一般用来初始化一些数据,在类加载时自动执行,只执行一次
-
执行顺序:\(静态代码块>匿名代码块>构造方法\)
-
-
静态导入包:
improt static
-
JDK 1.5 以后支持的使用静态导入包后,可以直接使用该包的方法,只需要
XX
不需要包.XX
来操作 -
例如:
未使用 improt static 的 输出语句Systm.out.println();
使用 improt static 的输出语句
import static java.lang.Math out.println();
-
5.4.3 final 关键字
- 在类中,使用 final 关键字所修饰和限定
- 那么这个类不能被继承,就是不能有子类
- 在方法中,使用 final 关键字修饰
- 那么这个方法不能被子类所覆盖
- 在字段或者局部变量(方法中的变量)中,使用 final 关键字
- 它们的值一旦给定,就不能更改,是一个只读量,而且只能被赋值一次
- 当一个字段被
static final
两个修饰符限定时,它可以表示常量- 例如:
MAth.PI
这种常量
- 例如:
- 关于赋值:
- 在定义
static final
变量时,若不给定初始值,则会按照默认值进行初始化- 数值类型为 0;boolean 类型为 false;引用类型为 null
- 在定义
final
变量时,若不是 static 变量,则必须且只能赋值一次,不能缺省- 这种变量的赋值方式有两种:一是在定义变量时赋初始值;二是在每一个构造方法中进行赋值
- 在定义
final
局部变量时,也必须且只能赋值一次。值可能不是常量,但其取值在变量存在期间不会发现改变
- 在定义
5.4.4 abstract 关键字
-
在方法中,abstract 修饰的方法称为抽象方法
-
作用:为所有子类定义一个统一的接口
-
抽象方法只需要声明,不需要实现,即使用分号
()
而不是{}
-
格式:
abstract retuenType abstractMethod([paramlist]);
-
-
-
在类中,使用 abstract 关键字修饰的类称为抽象类
-
例如:
//抽象类 public abstract class Action{ //抽象方法 public abstract void sum(){ …… } }
-
-
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
-
抽象类本身不能实例化,只能由子类来继承
- 与抽象方法类似,不能实现,只有方法声明,只能由子类来实现
-
子类继承抽象类,就必须实现抽象类中没有实现的抽象方法,否则该子类也为抽象类
5.5 内部类
-
内部类就是在一个类的内部再定义一个类,再定义的那个类对于原来的类来讲就被称为内部类,相反称为外部类
-
成员内部类
-
例如:
public class Outer{ …… public class Inner{ …… } }
调用外部类和内部类
public static void main(String[] args){ //调用外部类 Outer outer = new Outer(); //调用内部类 Outer.Inner inner = new Inner(); }
-
作用:
- 内部类可以操作外部类的私有属性、私有方法
-
-
静态内部类
-
例如:
public class Outer{ …… public static class Inner{ …… } }
-
-
局部内部类
-
例如:
public class Outer{ …… public void method{ class Inner{ public void in(){ …… } } } }
-
一般不这样使用,目前认识就行
-
-
匿名内部类
-
例如:
public class Outer{ public static void eat(){ …… } public static class Inner{ public static void main(String[] args){ new Outer().eat(); } } }
-
没有名字初始化类,不用将实例保存到变量中,就能使用对于方法
-
5.6 包机制
-
为了更好的组织类,Java 提供了包机制,用于区分类名的命名空间,解决名字空间、名字冲突
- 包与类的继承没有关系,一个子类与其父类可以位于不同包类
-
包的含义
- 一方面是名字空间、存储路径(文件夹)
- 一方面是可访问性(同一个包中的各个类,默认情况下是可相互访问)
-
包层次的根目录是由环境变量 CLASSPATH 来确定的
- 没有 package 语句时,称为无名包
-
命名规则
package pkg1[.pkg2[.pkg3...]];
-
一般利用公司域名倒置作为包名¥
-
例如:以 IDEA 为例
创建时输入IDEA 生成结果
-
如果发现生成有问题时:注意取消勾选
-
-
使用某一个包的成员,使用 improt 关键字导入该包
-
语法格式:
improt package1[.package2 [.package3 ]].(classname | *);
使用星号只能表示本层次下的所有类,不包括子层次下的类
-
Java 编译器自动导入包 java.lang.*
-