JAVA基础知识4
- static
- 静态成员变量
- 静态成员方法
- 解释
- 注意点
- 继承
- 父类(基类或超类)
- 子类(派生类)
- 使用继承的示例
- 解释
- 运行结果
- 成员变量的访问特点
- 成员方法的访问特点
- 构造方法的访问特点
- Java项目,包和类之间的联系
- 包的概念
- 包的声明
- 类和包的关系
- 包和类的示例
- 使用包的优点
- 导入包中的类
- 完整示例
static
在 Java 中,static
关键字可以用来修饰成员方法和成员变量。以下是它们的用法和需要注意的点。
静态成员变量
静态成员变量(也叫类变量)是属于类的,而不是属于类的实例。它们在类的所有实例之间共享。
public class Students {
private int id;
private String name;
private int age;
private static int studentCount = 0; // 静态成员变量
public Students(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
studentCount++; // 每创建一个实例,studentCount 增加
}
// Getter 和 Setter 方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static int getStudentCount() {
return studentCount; // 静态方法可以访问静态变量
}
@Override
public String toString() {
return "Students{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
静态成员方法
静态成员方法是属于类的,而不是属于类的实例。它们可以直接通过类名调用,而不需要创建类的实例。静态方法只能访问静态变量和调用其他静态方法。
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Students> list = new ArrayList<>();
list.add(new Students(1, "玛丽", 18));
list.add(new Students(2, "迪丽热巴", 35));
list.add(new Students(3, "赵丽颖", 18));
printStudent(list, 1);
// 打印学生总数
System.out.println("学生总数: " + Students.getStudentCount());
}
public static void printStudent(ArrayList<Students> list, int index) {
System.out.println("学生的id\t学生的名字\t学生的年纪");
System.out.println(list.get(index).getId() + "\t" + list.get(index).getName() + "\t" + list.get(index).getAge());
}
}
解释
-
静态成员变量:
private static int studentCount = 0;
是一个静态成员变量,用来统计创建的Students
对象的数量。studentCount
在类的所有实例之间共享,每创建一个新的Students
对象,它都会增加。
-
静态成员方法:
public static int getStudentCount()
是一个静态方法,用来获取studentCount
的值。- 静态方法可以直接通过类名调用,例如:
Students.getStudentCount()
。
-
静态方法中的调用:
- 在
main
方法中,通过printStudent(list, 1);
调用静态方法printStudent
打印list
中索引为1
的Students
对象的信息。 - 通过
Students.getStudentCount()
获取学生总数,并打印出来。
- 在
注意点
- 静态成员变量和静态成员方法是属于类的,而不是属于类的实例。
- 静态方法只能访问静态变量和调用其他静态方法,不能直接访问非静态变量或调用非静态方法。
- 静态方法通常用于工具类方法或与特定实例无关的操作。
继承
继承是面向对象编程中的一个重要概念,它允许一个类(子类)从另一个类(父类)继承属性和方法,从而实现代码重用和扩展。以下是一个简单的示例,展示如何在 Java 中实现继承。
父类(基类或超类)
public class Animal {
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void makeSound() {
System.out.println("Some generic animal sound");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
子类(派生类)
子类 Dog
继承了父类 Animal
,并可以添加自己的属性和方法。
public class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类的构造函数
this.breed = breed;
}
@Override
public void makeSound() {
System.out.println("Woof! Woof!");
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
@Override
public String toString() {
return "Dog{" +
"name='" + getName() + '\'' +
", age=" + getAge() +
", breed='" + breed + '\'' +
'}';
}
}
使用继承的示例
public class Main {
public static void main(String[] args) {
Animal genericAnimal = new Animal("Generic Animal", 5);
System.out.println(genericAnimal);
genericAnimal.makeSound();
Dog dog = new Dog("Buddy", 3, "Golden Retriever");
System.out.println(dog);
dog.makeSound();
}
}
解释
-
父类
Animal
:- 包含属性
name
和age
,以及方法makeSound
、getName
、setName
、getAge
、setAge
和toString
。 makeSound
方法在父类中提供了一个通用的实现。
- 包含属性
-
子类
Dog
:- 继承了
Animal
类的所有属性和方法。 - 添加了新的属性
breed
,以及相应的getter
和setter
方法。 - 重写了
makeSound
方法,为Dog
类提供特定的实现。 - 使用
super(name, age)
调用了父类的构造函数。
- 继承了
-
Main
类:- 创建了一个
Animal
对象和一个Dog
对象,分别调用它们的toString
和makeSound
方法,展示继承和方法重写的效果。
- 创建了一个
运行结果
Animal{name='Generic Animal', age=5}
Some generic animal sound
Dog{name='Buddy', age=3, breed='Golden Retriever'}
Woof! Woof!
通过这个示例,你可以看到继承如何在子类中复用父类的代码,同时通过方法重写实现特定行为。
在 Java 中,子类确实无法直接访问父类中的私有成员变量。但是,子类可以通过父类提供的公共方法(如 getter 和 setter 方法)间接访问和操作这些私有成员变量。在我们的例子中,子类 Dog 并没有直接访问父类 Animal 的私有成员变量 name 和 age,而是通过父类提供的公共方法(getName 和 getAge)来获取这些值。
解释
父类 Animal:
name 和 age 是私有成员变量,无法被子类直接访问。
提供了 getName、setName、getAge 和 setAge 等公共方法,允许子类通过这些方法间接访问和修改私有成员变量。
子类 Dog:
子类 Dog 没有直接访问父类 Animal 的私有成员变量 name 和 age。
在子类 Dog 的 toString 方法中,调用了 getName 和 getAge 方法来获取父类的私有成员变量值。
总结
私有成员变量:子类无法直接访问父类的私有成员变量。
公共方法:子类可以通过父类提供的公共方法(getter 和 setter)来访问和操作父类的私有成员变量。
构造方法不能被继承。
封装性:私有成员变量的设计是为了保持封装性,确保数据只能通过受控的方式访问和修改。
描写继承结构
成员变量的访问特点
成员方法的访问特点
构造方法的访问特点
Java项目,包和类之间的联系
在 Java 中,包和类之间有着密切的联系。包(package)用于组织类和接口,以避免命名冲突,并提供访问控制。以下是包和类之间关系的详细解释:
包的概念
- 包 是一组相关类和接口的集合。它们在逻辑上是相关的,可以在同一个包中进行分组。
- 包名通常是由小写字母组成的,以避免与类名发生冲突。
- 包可以嵌套,也就是说一个包可以包含多个子包。
包的声明
每个 Java 文件都可以选择性地包含一个包声明。包声明必须是文件的第一条语句(除非存在注释)。例如:
package com.example.myapp;
类和包的关系
-
类的组织:
- 类可以被组织到包中,通过包名来区分不同的类。
- 使用包可以避免类名冲突。例如,两个不同的开发者可以在不同的包中创建名称相同的类。
-
包的层次结构:
- 包可以有层次结构,例如
com.example.myapp
表示com
包下的example
子包,再下是myapp
子包。 - 这种层次结构使得类的组织更有条理,便于管理和维护。
- 包可以有层次结构,例如
-
访问控制:
- 包还提供了访问控制功能。例如,默认(包级)访问权限允许同一个包中的类相互访问,但不允许不同包中的类访问。
- 通过使用
public
、protected
和private
关键字,可以进一步控制类和类成员的访问权限。
包和类的示例
假设我们有一个包 com.example.myapp
,并在其中创建几个类。
// 文件:src/com/example/myapp/Main.java
package com.example.myapp;
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 30);
System.out.println(user);
}
}
// 文件:src/com/example/myapp/User.java
package com.example.myapp;
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
使用包的优点
- 命名冲突的避免:通过包名可以有效避免命名冲突。
- 代码的组织和管理:包有助于逻辑上组织代码,使项目更易于管理和维护。
- 访问控制:包提供了一种机制来控制类的访问权限,增强了代码的安全性。
导入包中的类
为了在一个类中使用另一个包中的类,必须使用 import
语句导入该类。例如:
import com.example.myapp.User;
public class Test {
public static void main(String[] args) {
User user = new User("Bob", 25);
System.out.println(user);
}
}
完整示例
假设我们有一个 Java 项目,目录结构如下:
src/
├── com/
│ └── example/
│ └── myapp/
│ ├── Main.java
│ └── User.java
Main.java
文件内容:
package com.example.myapp;
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 30);
System.out.println(user);
}
}
User.java
文件内容:
package com.example.myapp;
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
在这个示例中,我们通过包 com.example.myapp
来组织 Main
和 User
两个类。Main
类使用了 User
类,展示了包和类之间的联系。
希望这些解释能帮助你理解包和类之间的关系。如果有任何问题,请随时告诉我!