目录
封装
封装知识点
以下是Java封装相关的重要知识点:
一、访问修饰符
private(私有)
含义:这是实现封装的关键修饰符。将类的成员变量(属性)或方法声明为private后,它们只能在所属类的内部被访问。例如:
class Person {
private String name;
private int age;
}
用途:用于隐藏类的内部数据,防止外部类直接修改或访问这些数据,从而保证数据的安全性和完整性。
public(公共)
含义:公共的成员变量或方法可以被任何类访问。不过,在良好的封装实践中,一般不会直接将属性声明为public,而是通过public的方法来访问私有属性。例如:
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
}
用途:用于提供对外的接口,使得其他类能够与当前类进行交互,同时遵循封装的原则,不直接暴露内部数据。
含义:受保护的成员变量或方法可以被同一个包中的类以及该类的子类访问。例如:
package mypackage;
class Parent {
protected int protectedValue;
}
class Child extends Parent {
public void accessProtectedValue() {
System.out.println(protectedValue);
}
}
用途:在继承关系中使用,既允许子类访问父类的部分成员,又在一定程度上限制了外部类的访问,是一种介于private和public之间的访问控制方式。
二、getter和setter方法
getter方法(访问器方法)
定义:getter方法是一种公共的方法,用于获取私有属性的值。它的命名规范通常是 get 加上属性名(属性名首字母大写),如果属性类型为布尔型,也可以使用 is 加上属性名(属性名首字母大写)。例如:
class Circle {
private double radius;
public double getRadius() {
return radius;
}
}
作用:提供了一种安全的方式让外部类获取类内部的私有属性值,而不会直接暴露属性本身,这样可以在方法内部添加额外的逻辑,如对返回值进行格式化等。
setter方法(修改器方法)
定义:setter方法用于设置私有属性的值。它的命名规范通常是 set 加上属性名(属性名首字母大写)。例如:
class Circle {
private double radius;
public void setRadius(double newRadius) {
if (newRadius > 0) {
radius = newRadius;
}
}
}
作用:允许外部类修改类内部的私有属性,但可以在方法内部添加验证逻辑,确保传入的值是合法的,从而保证类的内部数据的正确性。
三、封装类的设计原则
单一职责原则
概念:一个类应该只有一个引起它变化的原因。在封装类时,类的功能应该尽可能单一。例如,一个 员工类应该主要关注员工相关的属性(如姓名、工号、工资等)和操作(如获取工资、计算奖金等),而不应该包含与员工无关的功能,如文件读取等。
好处:这样可以使类的结构更清晰,易于理解、维护和扩展。
高内聚性
概念:类内部的各个元素(属性和方法)应该紧密相关,共同完成类的一个或几个相关功能。
好处:高内聚性的类更加独立和稳定,内部逻辑更清晰,有助于提高代码的可维护性和复用性。
四、构造方法与封装
一.Java为什么要封装?
以下是Java中进行封装的几个重要原因:
一、数据隐藏与安全性
保护数据不被随意访问
在Java中,通过将数据成员声明为私有(private),可以防止外部类直接访问和修改这些数据。例如,一个银行账户类 BankAccount 可能有一个私有属性 private double balance; 来表示账户余额。如果没有封装,外部的任何代码都可以直接修改这个余额,这可能会导致数据的不一致性和安全漏洞。
防止外部干扰
封装可以隔离类的内部实现细节与外部代码。
二、提高代码的可维护性
易于修改内部实现
当一个类的内部实现需要改变时,由于封装将类的内部数据和操作与外部隔离开来,只需要修改类内部的代码,而不需要在所有使用这个类的地方进行修改。
代码的模块化
封装有助于将代码划分为独立的模块。
三、代码的复用性
提供统一的接口
封装后的类通过公共方法提供了一个统一的接口供外部使用。
隐藏复杂性
一个复杂的类可能内部包含了很多复杂的逻辑和数据处理过程。通过封装,外部代码不需要了解这些复杂性,只需要按照类提供的接口进行操作。这使得复杂的类更容易被重复使用。
Java构造
一、构造函数的基本概念
构造函数是一种特殊的方法,它在创建对象时被调用,用于初始化对象的状态。
构造函数的名称必须与类名相同。例如,如果有一个类名为 Person ,那么构造函数就应该命名为 Person 。
class Person {
// 这是一个构造函数
public Person() {
// 在这里可以进行初始化操作
}
}
二、默认构造函数
如果在类中没有显式地定义任何构造函数,Java编译器会自动为这个类生成一个默认构造函数。
class MyClass {
// 由于没有定义构造函数,编译器会生成一个默认构造函数
}
- 但是,一旦在类中定义了任何一个构造函数(无论是带参数还是不带参数),编译器就不会再自动生成默认构造函数了。
三、带参数的构造函数
可以根据需要定义带参数的构造函数,用于根据传入的不同参数值初始化对象的成员变量。
class Rectangle {
private int length;
private int width;
public Rectangle(int l, int w) {
length = l;
width = w;
}
}
四、构造函数的重载
在同一个类中,可以定义多个构造函数,只要它们的参数列表不同(参数的个数、类型或者顺序不同)。
class Circle {
private double radius;
// 无参数构造函数
public Circle() {
radius = 1.0;
}
// 带一个参数的构造函数
public Circle(double r) {
radius = r;
}
}
构造函数重载的好处是可以提供多种方式来创建对象,增加了类的灵活性。
五、this关键字在构造函数中的使用
当成员变量和局部变量(例如构造函数的参数)同名时,可以使用 this 关键字来区分成员变量和局部变量。
在构造函数中, this 表示当前正在创建的对象。
class Student {
private String name;
public Student(String name) {
this.name = name;
}
}
this 还可以用来在一个构造函数中调用同一个类的其他构造函数,但必须是构造函数中的第一条语句
class Book {
private String title;
private String author;
public Book() {
this("Untitled", "Unknown");
}
public Book(String title, String author) {
this.title = title;
this.author = author;
}
}
六、构造函数与继承的关系
在继承关系中,子类的构造函数会默认调用父类的无参数构造函数。
如果父类没有无参数构造函数,那么子类的构造函数必须显式地调用父类的构造函数,使用 super 关键字。
class Animal {
private String type;
public Animal(String type) {
this.type = type;
}
}
class Dog extends Animal {
public Dog(String breed) {
super("Dog");
// 可以在这里进行子类特有的初始化操作
}
}
当创建子类对象时,首先会执行父类的构造函数(如果有多层继承,会按照继承层次依次执行父类的构造函数),然后再执行子类的构造函数。
Java重载
以下是关于Java重载(Overloading)知识点
一、概念定义
基本概念
在Java中,重载是指在同一个类中定义多个方法,这些方法具有相同的名称但参数列表不同。这里的参数列表不同包括参数的个数、类型或者顺序不同
二、重载的识别依据
参数个数不同
可以通过定义不同参数个数的方法来实现重载。
public class PrintUtils {
public void print() {
System.out.println("Empty print");
}
public void print(String message) {
System.out.println(message);
}
}
这里的 print 方法有一个无参数版本和一个带一个 String 参数的版本。
参数类型不同
这是最常见的重载形式。即使方法名相同,只要参数类型不同就可以构成重载。
public class Type {
public void check(int num) {
System.out.println("Integer: " + num);
}
public void check(double num) {
System.out.println("Double: " + num);
}
}
参数顺序不同
当方法有多个参数时,参数顺序不同也可以构成重载。例如:
public class OrderCheck {
public void process(int num, String str) {
System.out.println("int: " + num + ", String: " + str);
}
public void process(String str, int num) {
System.out.println("String: " + str + ", int: " + num);
}
}
三、重载与返回类型
返回类型无关
方法的返回类型不能作为重载的依据,仅仅是返回类型不同而参数列表相同的方法不能构成重载。