- 1.认识类和对象
- 1.1 面向过程与面向对象
- 1.2 类的定义
- 1.3 类的实例化
- 1.4 null
- 2. static
- 2.1 static修饰的类属性
- 2.2 static修饰成员方法
- 3. 访问权限
- 3.1 public
- 3.2 private
- 4. 构造方法
- 5. this关键字
- 6. 代码块
在认识类前,我们先来了解一下面向过程和面向对象。
顾名思义 面向过程就是注重解决问题的过程中的行为,看重功能 。
面向对象就是注重解决问题中涉及到的主体 将数据和功能看成一个主体。
举个例子:
将大象放入冰箱
面向过程:将冰箱打开,放入大象,关上冰箱
面向对象:打开冰箱,放入,关上冰箱都是冰箱的行为,那么冰箱就可以看成一个主题
1.2 类的定义在Java中类是一类对象的统称,我们可以理解成类就是对象的模板,一个类可以实例化无数的对象。
Java中是引用类型,使用关键字class声明一个类。
类由字段(成员属性)成员方法、代码块、内部类、接口组成。
定义一个类:
class Person{
public String name;
public int age; //字段
public void eat(){ //成员方法
System.out.println("eat");
}
public void sleep(){
System.out.println("sleep");
}
}
1.3 类的实例化
用类类型创建一个对象的过程,成为类的实例化。
我们可以理解类为一个模板,那么一个模板就可以实例化出无数个对象。
在Java中用关键字new来实例化一个对象,通过’.'来访问类的成员属性以及成员方法。
实例化对象:
class Person{
public String name;
public int age; //字段
public void eat(){ //成员方法
System.out.println("eat");
}
public void sleep(){
System.out.println("sleep");
}
}
public class TestDemo{
public static void main(String[] args){
Person person1 = new Person();
Person person2 = new Person();//new实例化对象
person1.eat(); //同过对象的引用来调用成员方法
person2.eat();
person1.name = "张三";
person1.age = 18;
person2.name = "李四";
person2.name = 20;
}
}
每次创建出的一个对象都是独立的,person1和person2是引用变量其指向各自创建的对象,每次new一个对象后在堆上为这个对象开辟空间,将其地址保存在 person1 和 person2中,每个对象的属性是不同的。
注意:引用一定是在栈上吗?
要看在哪里定义的变量,如果是一个类中的引用,那么在创建这个对象的时候,这对象中的内容创建在堆上,而其中的引用也是在堆上,所以引用不一定在栈上。
1.4 nullnull在Java中为空引用,即该引用不指向任何一个对象
注意:一个对象的字段如果没有被初始化,那么会被默认设置一个值
规则:
- 整型和浮点型默认值为0
- 字符型的默认值为 'u0000’
- boolean类型为false
- 引用类型为null
被static修饰的成员属性是被放在方法区当中的,这个属性是属于类的,也就是说静态成员属性不需要对象就可使用,用类名即可调用。
class Person {
public static int age;
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person();
person1.age++;
System.out.println(person1.age);
person2.age++;
System.out.println(person2.age);
Person.age++;
System.out.println(Person.age);
}
}
从结果可知,静态成员变量是类的,它存放在方法区当中只有一份。
注意事项:
静态成员变量不可以定义在成员方法中,无论是静态成员方法还是普通非静态成员方法都不可以,静态成员变量就是属于类的。
class Person {
public static int age;
public void fun(){
static int a;
} //编译器会报错,语法不支持
}
2.2 static修饰成员方法
被static修饰的成员方法为静态成员方法,静态方法通过类名调用,不需要创建对象就可调用。
来看一段代码:
class Person {
public static int age;
public void fun(){
staticfun();
System.out.println("非静态成员方法");
}
public static void staticfun(){
System.out.println("hello");
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
person1.fun();
}
}
结论:普通方法中可以调用静态成员方法。
注意:但是静态方法中不能调用非静态成员方法。(静态方法是不依赖于对象,如果没有创建对象直接用用类调用静态方法,那么其中的非静态方法是需要创建对象,而此时没有对象可引用,那么会矛盾,所以静态方法中不创建对象是不可以调用非静态方法的)
小结:
-
静态成员变量必须在类内,方法外定义。
-
静态成员方法中只能调用静态成员方法,非静态方法中可以调用静态成员方法也可以调用非静态成员方法。
在前面定义的字段都是用public来修饰的,如果被public修饰的类字段以及成员方法时可以被其他类访问的。
3.2 private被private修饰的成员属性,只能在类内访问,类外不可以访问,此时的属性被封装。
那么如果要访问这个成员属性,该如何操作呢?可以设置一个接口来实现该属性的访问。
class Person {
private int age;
public void setAge(int age1){
age = age1;
}
public int getAge(){
return age;
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
person1.setAge(18);
System.out.println(person1.getAge());
}
}
这就实现了访问被private修饰的成员。
如果成员属性被封装,那么就要设置一个公开的接口来实现类外访问。
封装的好处:
- 类内部可以自由修改
- 隐藏了实现的细节
- 提高了安全性
注意:
class Person {
private int age;
public void setAge(int age){
age = age;
}
public int getAge(){
return age;
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
person1.setAge(18);
System.out.println(person1.getAge());
}
}
当形参名与要赋值的成员属性名相同时,此时会出现以上的现象,这里其实是形参给自己赋值(由于局部变量优先),要在成员属性前加上this表示当前对象的引用即可区分开。
public void setAge(int age){
this.age = age;
}
4. 构造方法
构造方法是一种特殊的方法,在使用关键字new实例化一个对象时就会被自动调用,用来初始化这个对象。
- 为new的对象的分配空间
- 调用对象的构造方法
方法组成:
-
- 方法名必须与类名相同
- 构造方法没有返回值类型声明
- 每一个类中至少存在一个构造方法
class Person {
private int age;
public void setAge(int age){
age = age;
}
public int getAge(){
return age;
}
public Person(){
System.out.println("无参构造方法");
}
public Person(int age){
System.out.println("有参构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person(18);
System.out.println(person1.getAge());
}
}
为什么是调用合适的构造方法,上面的代码可以看出,person1调用的是无参数的,person2调用有参数的。
class Person {
private int age;
public void setAge(int age){
age = age;
}
public int getAge(){
return age;
}
public Person(int age){
System.out.println("有参构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
}
}
这里报错可以得出,编译器不会再为我们提供无参数的构造函数,由于我们已经定义了一个构造函数,编译器就不会再提供。
注意:
- 如果类中没有定义构造方法,编译器会自动生成一个构造方法
- 构造方法支持重载
- 如果已经定义了构造方法,编译器就不会再提供
this表示当前对象引用,可以用this来访问对象的字段和方法。
- this.data 访问字段
- this.fun() 访问方法
- this() 调用当前对象的其他构造函数
只介绍第三种
class Person {
private int age;
public void setAge(int age){
age = age;
}
public int getAge(){
return age;
}
public Person(){
this(20);
System.out.println("无参构造方法");
}
public Person(int age){
this.age = age;
System.out.println("有参构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person(18);
}
}
注意事项:
- this()必须要在构造方法内定义,且只能定义一次,且必须在构造方法中先定义
这里我们介绍实例代码块和静态代码块。
class Person {
private int age;
{
System.out.println("实例代码块");
}
static{
System.out.println("静态代码块");
}
public Person(){
System.out.println("无参构造方法");
}
public Person(int age){
this.age = age;
System.out.println("有参构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person(18);
}
}
静态代码块只被执行一次,且在构造方法之前,在类的加载时就已经调用。
class Person {
private int age;
public static int a;
{
System.out.println("实例代码块");
}
static{
System.out.println("静态代码块");
}
public Person(){
System.out.println("无参构造方法");
}
public Person(int age){
this.age = age;
System.out.println("有参构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
System.out.println(Person.a);
}
}
静态代码块不需要对象即可被调用,但是实例代码块不不可以。
注意:
静态代码块中不可以使用当前对象的非静态成员属性。
结论:
- 静态代码块只被执行一次,且在构造方法之前,在类的加载时就已经调用。
- 静态代码块不需要对象即可被调用,但是实例代码块不不可以。



