文章目录
面向对象
Java是面向对象的程序设计语言, Java 语言提供了定义类、成员变量、方法等最基本的功能 。
类与对象
所有使用类定义的变量都是引用变量,它们将会引用到类的对象。也就是说,所有类是引用类型。
定义类
面向对象的程序设计过程中有两个重要概念:类(class)和对象(object,也被称为实例,instance),其中类是某一批对象的抽象,可以把类理解成某种概念。对象才是一个具体存在的实体,从这个意义上来看,日常所说的人,其实都是人的实例,而不是人类。
定义类语法格式
[修饰符] class 类名
{
零个到多个构造器定义...
零个到多个成员变量...
零个到多个方法...
}
在上边的语法格式中
- 修饰符可以是
public
,final
,abstract
,或者完全省略这三个修饰符 - 类名命名规则遵循
大驼峰命名法
规则:每个单词首字母大写,其他字母全部小写,单词与单词之间不要使用任何分隔符。- 例如
MyTest、HandleExcel、HandleRequests
类的组成
一个类通常包含三中最常见的成员。
- 构造器
- 构造器是一个类创建对象的根本途径,如果一个类没有构造器,这个类通常无法创建实例。
- 因此,Java语言提供了一个功能:如果程序员没有为一个类编写构造器,则系统会为该类提供一个默认的构造器。一旦程序员为一个类提供了构造器,系统将不再为该类提供构造器。
- 成员变量:成员变量用于定义该类或该类的实例所包含的状态数据。
- 方法:方法则用于定义该类或该类的实例的行为特征或者功能实现。
需要注意的点
- 类中的成员数量无限制。
- 类中各成员之间的定义顺序没有要求,各成员之间可以互相调用。但是
static
修饰的成员不能访问没有static
修饰的成员。
成员变量
定义成员变量语法格式
[修饰符] 类型 成员变量名 [=默认值];
成员变量详细说明
- 修饰符
- 可以省略
- 可以是
public
,protected
,private
,static
,final
,其中public
,protected
,private
三个最多只能出现一个,可以与static
,final
组合使用来修饰成员变量
- 类型
- 不可省略,可以是基本数据类型和引用数据类型。
- 成员变量名
- 遵循
小驼峰命名法
规则:第一个单词首字母小写,后面每个单词首字母大写,其他字母全部小写,单词与单词之间不要使用任何分隔符。
- 遵循
- 默认值
- 定义成员变量还可以指定 个可边的默认值
方法
定义方法语法格式
[修饰符] 方法返回值类型 方法名(形参列表)
{
//由零条或多条可执行语句组成的方法体
}
方法详细说明
- 修饰符
- 可以省略
- 可以是
public
,protected
,private
,static
,final
,其中public
,protected
,private
三个最多只能出现一个,可以与static
,final
组合使用来修饰方法
- 方法返回值类型
- 返回值类型可以是基本数据类型和引用类型
- 如果声明了方法返回值类型,方法体内必须提供一个
return
语句,返回一个变量或表达式。变量或者表达式的类型必须与此处声明的类型匹配。 - 如果未声明方法返回值类型,必须使用void声明该方法没有返回值。
- 方法名
- 方法名命名规则与成员变量命名规则一致。
- 形参列表
- 形参列表用于定义该方法可以接受的参数
- 格式:由零组或多组形参组成
- 零组就是值该方法没有形参
- 一组形参:
(数据类型 形参名)
- 多组形参:
(数据类型 形参名1, 数据类型 形参名2)
- 一旦定义方法时指定了形参列表,调用方法时必须传入对应的参数值(谁调用方法,谁负责为形参赋值)
- 方法体
- 方法体里多条可执行性语句之间有严格的执行顺序,排在方法体前面的语句总是先执行,排在方法体后面的语句总是后执行。
static
关键字
static
的真正作用就是用于区分成员变量、方法、内部类、初始化块这四种成员到底属于类本身还是属于实例。
在类中定义的成员,static
相当于一个标志,有static
修饰的成员属于类本身,没有static
修饰的成员属于该类的实例。
- 通常把
static
修饰的成员变量和方法也称为类变量、类方法。 - 不使用
static
修饰的普通方法、成员变量则属于该类的单个实例,而不属于该类。因此通常把不使用static
修饰的成员变量和方法也称为实例变量、实例方法。
构造器
构造器是一个特殊的方法,定义构造器的语法格式与定义方法的语法格式很像,定义构造器的语法格式如下:
[修饰符] 构造器名 (形参列表)
{
//由零条到多条可执行性语句组成的构造器执行体
}
构造器详细说明
- 修饰符
- 可以省略
- 可以是
public
,protected
,private
其中之一
- 构造器名字:构造器名字必须与类名相同。
- 形参列表:和定义方法形参列表的格式完全相同。
使用构造器时需要注意的点 - 构造器既不能定义返回值类型,也不能使用
void
声明构造器没有返回值。 - 如果为构造器定义了返回值类型,或使用
void
声明构造器没有返回值,编译时不会出错,但Java
会把这个所谓的构造器当成方法来处理——>它就不再是构造器。
构造器不是没有返回值吗,为什么不能用void来声明呢?
- 这是Java语法的规定
- 实际上,类的构造器是有返回值的。当使用new关键字来调用构造器时,构造器返回该类的实例,可以把这个类的实例当成构造器的返回值,因此构造器的返回值类型总是当前类,无需定义返回值类型。
- 必须注意:不要在构造器里显式使用
return
来返回当前类的对象,因为构造器的返回值是隐式的。
定义一个Person类
public class Person{
//定义两个成员变量
public String name;
public int age;
//定义一个say方法
public void say(String content){
System.out.println(content);
}
}
上边的Person类里没有手动定义构造器,系统自动为该类提供一个构造器,系统提供的构造器总是没有参数的。
Java中类的作用
- 定义变量
- 创建对象
- 调用类的类方法或访问类的类变量。
使用类
对象的产生和使用
创建对象的根本途径是构造器,通过new关键字来调用某个类的构造器即可创建这个类的实例。
创建对象
//使用Person类定义一个Person类型的变量
Person p;
//通过new关键字调用Person类的构造器,返回一个Person实例
//讲该Person实例赋值给p
p = new Person();
//上边代码可以简写成一行代码
Person p = new Person();
使用对象
Java的对象大致有如下作用
- 访问对象的实例变量(也叫实例属性)
- 调用对象的方法
注意点
- 类或实例访问方法或成员变量的语法是:
类.类变量|方法
,或者实例.实例变量|方法
static
修饰的方法和成员变量,既可通过类来调用,也可通过实例来调用- 没有使用
static
修饰的普通方法和成员变量,只可通过实例来调用 - 如果堆内存里的对象没有任何变量指向该对象,那么程序将无法再访问该对象,这个对象也就变了垃圾,Java的垃圾回收机制将回收该对象,释放该对象所占的内存区。
- 如果希望通知垃圾回收机制回收某个对象,只需要切断该对象的所有引用变量和它之间的关系即可,也就是把这些引用变量赋值为**
null
**。
代码示例
Person.java
package com.abc.part_four;
public class Person {
//定义两个成员变量
public String name;
public int age;
//定义一个say方法
public void say(String content) {
System.out.println(content);
}
}
PersonTest.java
package com.abc.part_four;
public class PersonTest {
public static void main(String[] args) {
Person p = new Person();
System.out.println("***************未对Person类的实例属性name,age进行赋值前***************");
System.out.println(p.name);
System.out.println(p.age);
p.name = "小明";
p.age = 21;
System.out.println("***************对Person类的实例属性name,age进行赋值后***************");
System.out.println(p.name);
System.out.println(p.age);
System.out.println("***************调用Person类的实例方法say***************");
p.say("人生苦短,Let's Go!");
}
}
运行PersonTest.java
输出以下结果
***************未对Person类的实例属性name,age进行赋值前***************
null
0
***************对Person类的实例属性name,age进行赋值后***************
小明
21
***************调用Person类的实例方法say***************
人生苦短,Let's Go!
大部分时候,定义一个类就是为了重复创建该类的实例,同一个的多个实例具有相同的特征,而类则是定义了多个实例的共同特征。从某个角度来看,类定义的是多个实例的特征,因此类不是一种具体存在,实例才是具体存在 。完全可以这样说:你不是人这个类,我也不是人这个类,我们都只是人的实例。
对象this
的使用
Java中this关键字总是指向调用该方法的对象。this作为对象的默认引用有两种情形:
- 构造器中引用该构造器正在初始化的对象。
- 在方法中引用调用该方法的对象。
在方法中引用调用该方法的对象
this
关键宇最大地作用就是让类中一个方法,访问该类里的另一个方法或实例变量。
代码示例
Dog1.java
package com.abc.part_four;
public class Dog1 {
public String dogName;
public void jump() {
System.out.println("Dog jump~");
}
public void run() {
dogName = "小花花";
Dog1 dog = new Dog1();
dog.jump();//假设Dog run的前提是Dog jump
System.out.println("Dog run~");
}
}
Dog2.java
package com.abc.part_four;
public class Dog2 {
public String dogName;
public void jump() {
System.out.println("Dog jump~");
}
public void run() {
dogName = "小花花";
this.jump();//假设Dog run的前提是Dog jump
System.out.println("Dog run~");
}
}
Dog3.java
package com.abc.part_four;
public class Dog3 {
public String dogName;
public void jump() {
System.out.println("Dog jump~");
}
public void run() {
dogName = "小花花";
jump();//假设Dog run的前提是Dog jump
System.out.println("Dog run~");
}
}
DogTest.java
package com.abc.part_four;
public class DogTest {
public static void main(String[] args) {
System.out.println("*********Dog1*********");
Dog1 d1 = new Dog1();
// 调用Dog1里的run方法,创建两个Dog对象
d1.run();
/**
* 这里产生了两个问题
* 第一个问题:Dog1类中run()方法中调用jum()方法时是否一定需要一个Dog对象?
* 第二个问题:是否一定需要重新创建一个Dog对象?
* 第一个问题的答案是肯定的,因为没有使用static修饰的成员变量和方法都必须使用对象来调用 。
* 第二个问题的答案是否定的,因为当程序调用run()法时,一定会提供一个Dog对象,这样就可以直接使用这个己经存在的Dog对象,而无须重新创建新Dog对象了.
* 因此需要在run()方法中获得调用该方法的对象,通过this关键字就可以满足这个要求。
*
* this可以代表任何对象,当this出现在某个方法体中时,它所代表的对象是不确定的,但它的类型是确定的:它所代表的只能是当前类的实例,只有当这个方法被调用时,它所代表的对象才被确定下来:谁在调用这个方法,this就代表谁。
* 因此将Dog1中run()方法中使用this关键字来调用jump()方法会更合适些。
* 代码如Dog2所示
*/
System.out.println("*********Dog2*********");
Dog2 d2 = new Dog2();
//调用Dog1里的run方法,只创建了一个Dog对象
d2.run();
/**
* this关键字可以省略
* 代码如Dog3所示
*/
System.out.println("*********Dog3*********");
Dog3 d3 = new Dog3();
d3.run();
}
}
对于static修饰的方法而言,可以使用类来直接调用该方法,static修饰的方法中不能使用this引用。
- 由于static修饰的方法不能使用this引用,所以static修饰的方法不能访问不使用static修饰的普通成员,因此Java语法规定:静态成员(包括方法、成员变量)不能直接访问非静态成员(包括方法、成员变量)。
静态方法直接访问非静态方法时引发错误代码示例
package com.abc.part_four;
public class StaticAccessNonStatic {
public void say1(){
System.out.println("一个简单的非静态方法");
}
public static void say2(){
System.out.println("一个简单的静态方法");
}
public static void main(String[] args){
//执行程序编译时会报错:Error:(11, 9) java: 无法从静态上下文中引用非静态 方法 say1()。
// 因为say1()是属于示例的方法不是属于类的方法。因此必须需要使用对象来调用该方法。
//say1();
/**
* 在上面的main()方法中直接调用say1()方法时,系统相当于使用this作为该方法的调用者,
* 而main()方法是static修饰的方法,static修饰的方法属于类,而不属于对象,因此调用static修饰的方法的主调总是类本身.
*/
//如果确实需要在静态方法里调用非静态方法。可以创建类对象,使用类对象来调用非静态方法。
new StaticAccessNonStatic().say1();//输出:一个简单的非静态方法
//执行不会报错
say2();//输出:一个简单的静态方法
}
}
大部分时候,普通方法访问其他方法、成员变量时无须使用**this
前缀 ,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用`this1**前缀。
构造器中引用该构造器正在初始化的对象(简单来说就是在构造器中使用this关键字)
this
引用也可以用于构造器中作为默认引用,由于构造器是直接使用new
关键宇来调用,而不是使用对象来调用的,所以this
在构造器中代表该构造器正在初始化的对象。
代码示例
package com.abc.part_four;
public class ThisInConstructor {
public String name;
//定义一个构造器
public ThisInConstructor() {
//在构造器里定义一个name变量
String name;
//使用this代表该构造器正在初始化的对象
//下面的代码将会把该构造器正在初始化的对象的name成员变量设置成`小花花`
this.name = "小花花";
}
public static void main(String[] args) {
System.out.println(new ThisInConstructor().name);//小花花
}
}
程序输出
小花花