Java是面向对象的程序设计语言, Java 语言提供了定义类、成员变量、方法等最基本的功能 。
所有使用类定义的变量都是引用变量,它们将会引用到类的对象。也就是说,所有类是引用类型。
面向对象的程序设计过程中有两个重要概念:类(class)和对象(object,也被称为实例,instance),其中类是某一批对象的抽象,可以把类理解成某种概念。对象才是一个具体存在的实体,从这个意义上来看,日常所说的人,其实都是人的实例,而不是人类。
定义类语法格式
[修饰符] class 类名
{
零个到多个构造器定义...
零个到多个成员变量...
零个到多个方法...
}
在上边的语法格式中
public
,final
,abstract
,或者完全省略这三个修饰符大驼峰命名法
规则:每个单词首字母大写,其他字母全部小写,单词与单词之间不要使用任何分隔符。
MyTest、HandleExcel、HandleRequests
一个类通常包含三中最常见的成员。
需要注意的点
static
修饰的成员不能访问没有static
修饰的成员。定义成员变量语法格式
[修饰符] 类型 成员变量名 [=默认值];
成员变量详细说明
public
,protected
,private
,static
,final
,其中public
,protected
,private
三个最多只能出现一个,可以与static
,final
组合使用来修饰成员变量小驼峰命名法
规则:第一个单词首字母小写,后面每个单词首字母大写,其他字母全部小写,单词与单词之间不要使用任何分隔符。定义方法语法格式
[修饰符] 方法返回值类型 方法名(形参列表)
{
//由零条或多条可执行语句组成的方法体
}
方法详细说明
public
,protected
,private
,static
,final
,其中public
,protected
,private
三个最多只能出现一个,可以与static
,final
组合使用来修饰方法return
语句,返回一个变量或表达式。变量或者表达式的类型必须与此处声明的类型匹配。(数据类型 形参名)
(数据类型 形参名1, 数据类型 形参名2)
static
关键字static
的真正作用就是用于区分成员变量、方法、内部类、初始化块这四种成员到底属于类本身还是属于实例。
在类中定义的成员,static
相当于一个标志,有static
修饰的成员属于类本身,没有static
修饰的成员属于该类的实例。
static
修饰的成员变量和方法也称为类变量、类方法。static
修饰的普通方法、成员变量则属于该类的单个实例,而不属于该类。因此通常把不使用static
修饰的成员变量和方法也称为实例变量、实例方法。构造器是一个特殊的方法,定义构造器的语法格式与定义方法的语法格式很像,定义构造器的语法格式如下:
[修饰符] 构造器名 (形参列表)
{
//由零条到多条可执行性语句组成的构造器执行体
}
构造器详细说明
public
,protected
,private
其中之一void
声明构造器没有返回值。void
声明构造器没有返回值,编译时不会出错,但Java
会把这个所谓的构造器当成方法来处理——>它就不再是构造器。构造器不是没有返回值吗,为什么不能用void来声明呢?
return
来返回当前类的对象,因为构造器的返回值是隐式的。public class Person{
//定义两个成员变量
public String name;
public int age;
//定义一个say方法
public void say(String content){
System.out.println(content);
}
}
上边的Person类里没有手动定义构造器,系统自动为该类提供一个构造器,系统提供的构造器总是没有参数的。
创建对象的根本途径是构造器,通过new关键字来调用某个类的构造器即可创建这个类的实例。
//使用Person类定义一个Person类型的变量
Person p;
//通过new关键字调用Person类的构造器,返回一个Person实例
//讲该Person实例赋值给p
p = new Person();
//上边代码可以简写成一行代码
Person p = new Person();
Java的对象大致有如下作用
注意点
类.类变量|方法
,或者实例.实例变量|方法
static
修饰的方法和成员变量,既可通过类来调用,也可通过实例来调用static
修饰的普通方法和成员变量,只可通过实例来调用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引用。
静态方法直接访问非静态方法时引发错误代码示例
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
引用也可以用于构造器中作为默认引用,由于构造器是直接使用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);//小花花
}
}
程序输出
小花花