类和类的构成
简单说一下以下的这五部分:
(属性 方法 构造器 代码块 内部类)
1. 属性
成员变量 vs 局部变量
相同点:
1. 遵循变量声明的格式:数据类型 变量名 = 初始化值
2. 都有作用域
不同点:
1. 声明的位置不同。
成员变量:声明在类里,方法外
局部变量:声明在方法内,方法的形参部分,代码块内
2. 修饰符
成员变量的修饰符有四个:public private protected 缺省
局部变量没有修饰符,与所在的方法修饰符相同。
3. 初始化值
成员变量一定有初始化值(如果不显式的赋值,则为默认初始化值)
局部变量一定要显式的赋值
4. 二者在内存中存放的位置不同
成员变量:存在于堆空间中
局部变量:栈空间中
2. 方法
- 格式
权限修饰符 返回值类型 方法名 (形参){} - 返回值类型
void:表示此方法不需要返回值
有返回值:在方法最后要加 return + 返回值类型对应的变量 - 方法内可以调用本类的其他属性和方法,但是方法内不能再定义方法。
3. 构造器
- 构造器的作用:创建对象,并给创建的对象的属性赋值。
- 设计类时,如果没有显式的声明类的构造器,程序会默认提供一个空参的构造器。
- 一旦显式的定义类的构造器,就不再提供默认构造器
- 声明构造器的格式:权限修饰符 类名(形参){}
- 类的多个构造器之间构成重载。
tips:类对象的属性赋值的先后顺序:
属性的默认初始化->属性的显式初始化或代码块初始化->通过构造器初始化->通过对象.属性赋值。
4. 代码块
- 作用:用于初始化类的属性
- 分类
- 静态代码块:(用static修饰)
- 里面可以有输出语句
- 随着类的加载而加载,而且只被加载一次
- 多个静态代码块之间按照顺序结构执行
- 静态代码块的执行要早于非静态代码块的执行。
- 静态的代码块中只能执行静态的结构(类属性,类方法)
- 非静态代码块:
- 可以对类的属性(静态的 & 非静态的)进行初始化操作,同时也可以调用本类声明的方法(静态的 & 非静态的)
- 里面可以有输出语句
- 一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行。
- 每创建一个类的对象,非静态代码块就加载一次。
- 非静态代码块的执行要早于构造器。
- 静态代码块:(用static修饰)
5. 内部类
- 分类
- 成员内部类
- 静态内部类(用static修饰)
- 非静态内部类
- 局部内部类
- 匿名内部类
- 成员内部类
- 作用
- 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
- 内部类的方法可以直接访问外部类的所有数据,包括私有的数据。
- 匿名内部类适合用于创建仅需要一次使用的类。
- 各个内部类的介绍
3.1 成员内部类
- 内部类定义在外部类内部,相当于外部类的一个成员变量的位置,内部类可以使用任意访问控制符。
- 内部类中的方法可以直接访问外部类中的数据,而不受访问控制符的影响。
- 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去new一个内部类对象。
public class TestInnerClass {
public static void main(String[] args) {
//创建静态内部类的对象:可以直接通过外部类调用静态内部类的构造器
Person.Dog d = new Person.Dog();//Person.new Dog();
//Person.Bird b = new Person.Bird();
//创建非静态的内部类的对象:必须先创建外部类的对象,通过外部类的对象调用内部类的构造器
Person p = new Person();
Person.Bird b = p.new Bird();//new p.Bird();
b.info();
b.setName("王五");
}
}
class Person{
String name = "张三";
int age;
//成员内部类(非static的)
class Bird{
String name = "赵四";
int id;
public Bird(){
}
public void setName(String name){
System.out.println(name);//王五
System.out.println(this.name);//赵四
System.out.println(Person.this.name);//张三
}
public void info(){
show();
}
}
//成员内部类(静态内部类)
static class Dog{
}
public void show(){
System.out.println("我是show()方法");
}
3.2 局部内部类
定义:把一个内部类放在方法里定义。
作用域:仅在该方法里有效。(因此实际开发中很少用到)
tips:由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类不能使用访问控制符和static修饰符修饰。
public class LocalInnerClass{
public static void main(String[] args){
//定义局部内部类
class InnerBase{
int a;
}
class InnerSub extends innerBase{
int b;
}
InnerSub is = new InnerSub();
is.a = 5;
is.b = 8;
System.out.println("a:" + is.a + ",b:" + is.b);
}
}
3.3 匿名内部类
格式:
new 实现接口() | 父类构造器(实参列表){
//匿名内部类的类体部分
}
规则:
- 匿名内部类不能是抽象类。因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。
- 匿名内部类不能定义构造器。因为匿名内部类没有类名,所以不能定义构造器,但是可以定义初始化块。
补:
1. 类和对象
类(是某一批对象的抽象,可以理解为某种概念,比如:人类)
对象 (具体存在的实体,比如:某一个人)
①如何创建对象: 类名 对象名 = new 类名()
如:Person p = new person();
②使用对象:对象.属性 或 对象.方法
2. 类的初始化内存解析
栈(stack):局部变量、对象的引用名、数组的引用名
堆(heap):new的东西(如:对象的实体)、成员变量
方法区:含字符串常量
静态域:声明为static的变量