文章目录
类和对象
1.类和对象的介绍
- 类:类是一个模板,它描述一类对象的行为和状态。
- 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
2.类和对象的关系
- 类就是一类对象的统称。对象就是这一类具体化的一个实例;
- 类创建对象的过程成为实例化;
- 使用关键字new可以创建实例化一个对象;
- 对象的引用使用字符 “.” 访问对象中的变量和方法;
- 同一个类可以实例化多个对象;
3.类的变量、方法、代码块
3.1变量
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。局部变量存储于栈上。
- 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。静态的成员变量存储于方法区,普通的成员变量存储于堆。
- 类变量(静态成员变量):被 static 修饰。
- 普通成员变量(非静态):不被static修饰。
- 这里关注点在默认值:局部变量可以直接声明在方法中不初始化,前提是你不使用它,但是不使用还声明干什么,所以局部变量必须初始化,没有默认值,可以直接或者间接初始化(间接以最后一次为准)而成员变量不初始化有相应的默认值!
3.2成员变量小结
- 普通成员变量是定义在类中方法外的,它属于对象的;
- 静态成员变量被static修饰,它属于类,建议使用类名直接调用,当然也可以使用对象的引用调用;
- 注意方法中不能定义静态变量,静态方法和普通方法都不行;
- 注意静态成员变量是存储在方法区的,即使有多个对象,它只有一份;
3.3方法
Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
3.4方法小结(※)
-
被static修饰的方法为静态方法,它属于类,建议使用类名直接调用,当然也可以使用对象的引用调用,普通方法属于对象;
-
静态方法和普通方法中的调用规则:
- 普通方法中可以直接调用当前类的静态方法和普通方法;
- 静态方法可以直接调用当前类的静态方法,但是不能直接调用当前类的普通方法,且不能直接使用普通成员变量,必须再实例化对象后在调用。(如main函数中想直接调用自定义函数,用static修饰就可以直接调用)
3.5static关键字
在变量和方法中都提到了这个关键字,当被它修饰,则为静态的。
static可以修饰成员变量、方法、代码块和类。
code一下static的作用:静态的变量和方法属于类
被static修饰,它属于类,建议使用类名直接调用,当然也可以使用对象的引用调用
class stu {
public int id;
public static String address = "beijing";
public static void fun() {
System.out.println("hello!");
}
}
public class Demo03 {
public static void main(String[] args) {
stu s1 = null;
System.out.println(s1.address);
System.out.println(stu.address);
s1.fun();
stu.fun();
}
}
结果:
4.封装
何为封装?
封装(Encapsulation)可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
4.1实现封装
被 private 修饰的成员变量或者成员方法, 属性和方法为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。这也就是private的访问权限,使得访问权限限制在类内。
public class Person {
private String name;
private int age;
}
4.2getter和setter方法
如何访问私有字段?
对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问。即getter和setter方法。通过这个方法来访问属性。
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
5.this关键字
this表示当前对象引用(注意不是当前对象),可以借助 this 来访问对象的字段和方法。
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
在上面setter方法中,使用到了this关键字,它表示把参数age赋值给当前对象的私有属性age,如果不加this关键字,则表示形参age自己赋值自己。
采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
this的使用
- this.data 调用当前对象的变量
- this.func() 调用当前对象的方法
- this(…) 调用当前对象的构造函数,它只能放在构造函数中使用,且只能在第一行使用,注意只能在构造方法中使用一次,不能多次使用不同的构造函数!
6.构造方法(※)
6.1什么是构造方法?
用于实例化对象!
当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值,不是void!。
通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象。
不管你是否自定义构造方法,所有的类都有构造方法,因为 Java 自动提供了一个默认不带参数的构造方法,默认构造方法的访问修饰符和类的访问修饰符相同(类为 public,构造函数也为 public;类改为 protected,构造函数也改为 protected)。
注意,一旦你定义了自己的构造方法,默认构造方法就会失效。就是没有不带参的构造方法,如果需要则可以自行显示生成一个默认构造方法,甚至生成其他构造方法 ,当类中有多个构造函数时,构成了重载;
6.2实例化对象最后必须调用构造方法:
public class Demo {
public int age;
public String sex;
public Demo() { //构造方法
}
public Demo(int age, String sex) { //构造方法
this.age = age;
this.sex = sex;
}
public static void main(String[] args) {
Demo demo = new Demo(22,"male");
}
}
为什么说this是当前对象的引用?如上实例化一个对象,在调用构造方法后才产生对象。所以this表示当前对象的引用。
6.3构造方法小结
- 方法名必须和类名相同;
- 无返回值,不是void;
- 可以定义多个不同的构造方法,构成重载,java会根据你的参数列表调用相应的构造函数;
- 如果在类中不定义构造方法,编译器会默认在类中生成一个不带参数的构造方法;
- 注意当没有定义任何构造方法,实例化对象时,会直接调用默认不带参数的构造方法,但是当定义了一个或者多个构造方法时,实例化对象时,必须调用所定义的构造方法,编译器不会帮你生成不带参数的构造方法;
7.代码块
7.1两种特殊代码块
- 实例代码块也叫构造代码块(不加任何修饰)。一般用于初始化实例成员变量。实例代码块只有在创建对象时才会执行。
- 静态代码块,使用static定义的代码块。一般用于初始化静态成员变量。静态代码块不管生成多少个对象,其只会执行一次。
public class Person {
public int id;//实例变量
private String name;//实例变量
private int age;//实例变量
public static String adress;//静态变量
private static int cnt;//静态变量
//实例代码块
{
id = 111111;
name = "java";
age = 20;
}
//静态代码块
static{
adress = "beijing";
cnt = 6;
}
}
7.2代码块小结
1. 当实例化对象时,先执行静态代码块,再执行实例代码块,然后构造方法;
2. 注意,当多次实例化对象时,静态代码块只会被执行一次;
3. 当直接调用类的静态成员变量时,静态代码块也会被执行,也就是说不是非得实例化对象才能被执行;
8.思考
引用一定在栈上吗?
当然不是,如成员变量是引用,则是在堆上的
class Person {
public int id;
private String name;
}
class stu{
Person person = new person(); // 引用
public int id;
public String name;
}
public class Demo {
public static void main(String[] args) {
stu s = new stu();
s.id = 180;
s.name = "cc";
...
}
}
小结:s和person都是对象的引用,但是所处的位置是不同的。
当在main方法中,s是局部变量,那它是在栈上的;而stu类中的person是普通的成员变量,那么它是在堆上的。
图解: