【这句看着晕就忽略】Java是以对象为中心的,最小的程序单位就是类,整个java程序由一个一个类组成,可以把类当成一种自定义的引用类型,可以使用类来定义变量,这种类型的变量统称为引用变量。
面向对象的程序中有两个比较重要的概念一个是【类】,另一个是【对象】或者叫做【类的实例】,非常形象的举个例子:地球上的人属于【人】类,人类可以有两个子类【男/女】,其中【男】类的对象或者具体的实例可以是【张三】
[修饰符] class 类名// [修饰符]可以是public、final、abstract
{
零个到多个构造器定义...
零个到多个成员变量...
零个到多个方法...
}
[修饰符]类型 成员变量[=默认值];
[修饰符]方法返回值类型 方法名(形参列表)
{
//由零条或者多条执行语句组成的方法体
}
构造器是一个特殊的方法,定义构造器的语法格式与定义方法的语法格式很像
[修饰符]构造器名(形参列表)
{
//由零调到多条可执行语句组成的构造器执行体
}
public class Person
{
// 下面定义了两个成员变量
public String name;
public int age;
// 下面定义了一个say方法
public void say(String content)
{
System.out.println(content);
}
}
public class PersonTest
{
public static void main(String[] args)
{
// 使用Peron类定义一个Person类型的变量
Person p;
// 通过new关键字调用Person类的构造器,返回一个Person实例,
// 将该Person实例赋给p变量。
p = new Person();
// Person p = new Person();
// 访问p的name实例变量,直接为该变量赋值。
p.name = "davieyang";
// 调用p的say方法,声明say()方法时定义了一个形参,
// 调用该方法必须为形参指定一个值
p.say("Java语言很简单,学习很容易!");
// 直接输出p的name实例变量,将输出 davieyang
System.out.println(p.name);
// 将p变量的值赋值给p2变量
var p2 = p;
}
}
与数组类型类似,类也是一种引用数据类型,因此程序中定义的Person类型的变量实际上是一个引用,它被存放在栈内存中,并指向实际的Person对象,而真正的Person对象存放在堆内存中,P只是存储了一个地址值不包含任何实际数据。
// 将p变量的值赋值给p2变量
var p2 = p;
this关键字总是指向调用该方法的对象,作为对象的的默认引用有两种形式:
public class Dog
{
// 定义一个jump()方法
public void jump()
{
System.out.println("正在执行jump方法");
}
// 定义一个run()方法,run()方法需要借助jump()方法
public void run()
{
// var d = new Dog();
// d.jump();
// 使用this引用调用run()方法的对象
this.jump();
System.out.println("正在执行run方法");
}
}
public class DogTest
{
public static void main(String[] args)
{
// 创建Dog对象
var dog = new Dog();
// 调用Dog对象的run()方法
dog.run();
}
}
public class StaticAccessNonStatic
{
public void info()
{
System.out.println("简单的info方法");
}
public static void main(String[] args)
{
// 因为main()方法是静态方法,而info()是非静态方法,
// 调用main()方法的是该类本身,而不是该类的实例,
// 因此省略的this无法指向有效的对象
info();
}
}
编译这段代码会报错无法从静态上下文中引用非静态方法infor()
info()属于实例方法,而不是类方法,因此必须使用对象来调用该方法,在main()方法中直接调用info()方法时,系统相当于使用this作为该方法的调用者,然而main()方法是个static修饰的方法,static修饰的方法属于类而不是对象,因此调用static修饰的方法的主调总是类本身。
java编程时不要使用对象去调用static修饰的成员变量、方法,而是应该是用类去调用static修饰的成员变量、方法
修改代码如下:
public class StaticAccessNonStatic
{
public void info()
{
System.out.println("简单的info方法");
}
public static void main(String[] args)
{
// 创建一个对象作为调用者来调用info()方法
new StaticAccessNonStatic().info();
}
}
虽然大部分时候,普通方法访问其他方法、成员变量时无需使用this前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用this前缀。
this引用也可以用于构造器中作为默认引用,由于构造器是直接使用new关键字来调用,而不是使用对象来调用,所以this在构造器中代表该构造器正在初始化的对象
public class ThisInConstructor
{
// 定义一个名为foo的成员变量
public int foo;
public ThisInConstructor()
{
// 在构造器里定义一个foo变量
int foo = 0;
// 使用this代表该构造器正在初始化的对象
// 下面的代码将会把该构造器正在初始化的对象的foo成员变量设为6。
this.foo = 6;
}
public static void main(String[] args)
{
// 所有使用ThisInConstructor创建的对象的foo成员变量
// 都将被设为6,所以下面代码将输出6。
System.out.println(new ThisInConstructor().foo);
}
}
当this作为对象的默认引用使用时,程序可以像访问普通引用变量一样来访问这个this引用,甚至可以把this当成普通方法的返回值。
public class ReturnThis
{
public int age;
public ReturnThis grow()
{
age++;
// return this返回调用该方法的对象
return this;
}
public static void main(String[] args)
{
var rt = new ReturnThis();
// 可以连续调用同一个方法
rt.grow()
.grow()
.grow();
System.out.println("rt的age成员变量值是:" + rt.age);
}
}
如果在某个方法中把this作为返回值,则可以多次连续调用同一个方法,使得代码更简洁,但也会造成实际意义的模糊。