Java面向对象基础知识笔记(二)
1. this关键字
this
关键字代表当前对象的引用,可以用于访问当前对象的成员变量、成员方法和构造方法。在以下情况下常用到 this
:
- 使用 this 调用成员变量,解决成员变量与局部变量的同名冲突。
public class Person {public String name;public void setName(String name) {// 成员变量与局部变量不同名,this 可以省略。this.name = name;}
}
- 使用 this 调用成员方法。
public class Person {public void eat() {}public void work() {// this 调用成员方法时,可以省略 thisthis.eat();}
}
- 使用 this 调用重载的构造方法,只能在构造方法中使用,且必须是构造方法的第一条语句。
public class Person {public String name; public int age;public Person(String name) {this.name = name;} public Person(String name, int age) {// 调用重载的构造方法this(name);this.age = age;}
}
因为 this 是在对象内部代表自身的引用,所有 this 只能调用实例变量、实例方法和构造方法,不能调用类方法、类变量也不能调用局部变量
2. 包
2.1 包的作用
包(Package)用于组织和管理 Java 程序,将相同功能或类别的类放在同一个包中。包的作用如下:
- 存放类:包中能够存放类,易于找到和使用相应的类文件
- 命名空间管理:避免类名冲突。
- 访问控制:通过访问修饰符控制包内的类对外的可见性。
- 封装性:隐藏包内实现细节,对外提供接口。
2.2 包的声明
在 Java 代码文件的开头使用 package
关键字声明所属的包,通常与文件路径相对应。
- 包的声明必须是 Java 源文件中的第一条非注释性的语句,而且源文件只能有一个包声明语句,设计的包需要与文件系统结构相对应。
例如,一个名为 “com.example” 的包,可以这样声明:
package com.example;
1. 命名包不能以 java、javax 开头。
2. 同包下或者子包下的类不需要导包,java.lang 包下的类不需要导包。
3. 使用非同包下的类需要先导包或者使用全限定类名。
3. 访问修饰符
Java 中有四种(三个,一个为空)访问修饰符,用于控制类、成员变量和方法的访问权限:
public
:公共访问,在所有类内可见。protected
:受保护访问,同包内和子类可见。private
:私有访问,仅在当前类内可见。- (不写)
package-private
或package-access
:默认访问修饰符,仅在同一包内可见。
3.1 修饰类的访问修饰符
类的访问修饰符可以是 public
或 (不写) package-private
。
public class MyClass
:该类对所有其他类都可见。class MyClass
:该类仅对同一包内的其他类可见。
3.2 修饰成员、构造方法的访问修饰符
成员变量、方法和构造方法的访问修饰符可以是 public
、protected
、private
或 (不写) package-private
。
public int num
:该成员对所有其他类都可见。protected String name
:该成员对同一包内的其他类和子类可见。private double price
:该成员仅对当前类可见。int count
:该成员仅对同一包内的其他类可见。
4. 封装
4.1 什么是封装
封装(Encapsulation)是面向对象编程中的一项重要原则,指的是将数据和对数据的操作封装在一个类中,通过公共接口控制对数据的访问。
4.2 为什么要封装
封装有以下好处:
- 隐藏实现细节:只暴露必要的接口,隐藏实现细节,更好地控制数据的正确性和完整性。
- 提高安全性:通过访问修饰符限制对数据的访问,避免非法操作。
- 简化使用:外部代码无需关注内部实现,只需调用公共接口即可。
4.3 如何封装
在类中,可以使用 private
访问修饰符来限制成员变量的直接访问。通过提供公共的 getter 和 setter 方法来间接访问和修改私有成员变量。
- Getter 方法:
- 命名规则:使用属性名前加上 “get” 作为方法名前缀,属性名首字母通常大写。
- 返回类型:通常与属性的类型相同。
- 方法体:直接返回属性值。
- Setter 方法:
- 命名规则:使用属性名前加上 “set” 作为方法名前缀,属性名首字母通常大写。
- 返回类型:通常只有一个参数,参数类型与属性的类型相同。
- 方法体:将传入的参数值赋给属性。
- 布尔类型属性的 Getter 方法:
- 命名规则:使用属性名前加上 “is” 作为方法名前缀,属性名首字母通常大写。
- 返回类型:通常是布尔类型。
- 方法体:返回属性的值。
示例代码:
public class Person {private String name;public String getName() {return this.name;}public void setName(String name) {this.name = name;}
}
对字段值设置合法性检查,需要在 setter 方法中进一步利用条件判断语句进行赋值限制
5. 包装类【了解】
5.1 有哪些包装类
Java 提供了包装类(Wrapper Class)来表示基本数据类型的对象形式,如下:
基本类型 | 包装类 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
5.2 默认值是 null
包装类的默认值都是 null
。
例如,Integer
类的初始值是 null
,而不是基本类型 int
的默认值 0
。
示例代码:
Integer num = null;
System.out.println(num); // 输出为 null
5.3 自动装箱、自动拆箱
Java 提供了自动装箱(Autoboxing)和自动拆箱(Unboxing)机制,使得基本类型和包装类之间的转换更加方便。
- 自动装箱:将基本类型自动转换为对应的包装类对象。
- 自动拆箱:将包装类对象自动转换为对应的基本类型。
示例代码:
// 自动装箱
Integer i = 42;// 自动拆箱
int num = i;
6. 继承
6.1 什么是继承
继承(Inheritance)是面向对象编程中的一个重要概念,允许子类继承父类的属性和方法。它提供了一种有效的方式来重用代码和组织类层次结构。但是过度使用继承可能会导致复杂的代码结构和性能问题,因此需要谨慎使用。
- 子类可以继承父类的非私有属性和方法。
- 子类可以添加自己的属性和方法。
- 子类的构造方法可以调用父类的构造方法。
- Object 类是所有类的根类。
- Java 中类只支持单一继承,每一个类只能有一个父类(直接父类)。
6.2 为什么要继承
继承有以下好处:
- 代码重用:子类可以继承父类已有的代码。
- 派生性:子类是父类的一种特殊形式,具有父类的共性。
- 扩展性:通过添加新的属性和方法,子类可以扩展父类的功能。
6.3 怎么继承
在 Java 中,使用 extends
关键字实现继承。子类可以继承父类的非私有成员和方法,并可以重写父类的方法。
示例代码:
public class Animal {public void eat() {System.out.println("Animal is eating.");}
}public class Cat extends Animal {@Overridepublic void eat() {System.out.println("Cat is eating.");}
}
6.4 继承了什么
继承使子类获得了父类的以下内容:
- 非私有成员变量。
- 非私有方法。
- 父类的构造方法。
6.5 直接继承、间接继承
- 直接继承:子类只有一个直接父类。
- 间接继承:子类的父类也是其他类的子类。
示例代码:
public class Animal { }public class Mammal extends Animal { }public class Cat extends Mammal { }
在上述示例中,Cat
类直接继承自 Mammal
,而 Mammal
类间接继承自 Animal
。
6.6 方法重写 (@Override)
子类可以重写父类的方法,即提供自己的实现。使用 @Override
注解可以明确表示一个方法是重写父类的方法。
示例代码:
public class Animal {public void eat() {System.out.println("Animal is eating.");}
}public class Cat extends Animal {@Overridepublic void eat() {System.out.println("Cat is eating.");}
}
6.7 instanceof 的使用
instanceof
是 Java 中的关键字,用于判断一个对象是否是某个类的实例或子类的实例。它可以用来做类型检查和类型转换。
示例代码:
Animal cat = new Cat();if (cat instanceof Cat) {System.out.println("cat is an instance of Cat");
}if (cat instanceof Animal) {System.out.println("cat is an instance of Animal");
}
6.8 Object是所有类的父类
在 Java 中,Object
是所有类的直接或间接父类。它定义了一些通用方法,如 equals()
、toString()
等。
6.9 final 的使用
final
是 Java 中的关键字,可以修饰类、方法和变量。
final class MyClass
:该类不能被继承。final void myMethod()
:该方法不能被子类重写。final int num
:该变量是一个常量,不能再次赋值。
6.10 实例化的过程【大的顺序】
在 Java 中,实例化一个对象的过程主要分为以下几个步骤:
- 分配内存空间,创建对象。
- 调用父类的构造方法(从顶级父类开始)。
- 按声明顺序依次初始化成员变量(包括父类的成员变量)。
- 执行构造方法的代码块和构造方法体。
- 返回创建的对象的引用。