类
类:构造(construct)对象的模板,由类构造对象的过程称为创建类的实例。
例如:人类有名字、性别、肤色等属性。
封装:将数据和行为组合在一个包里面,对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域,操作数据的过程称为方法(method)。
例如get & set方法对数据进行操作。
继承:通过扩展一个类来建立另一个类的过程。扩展后的新类具有所扩展的类的全部属性和方法。在新类中,只需要提供适用于这个新类的新方法和数据域。
对象
状态:对象的属性或数据,用于描述对象的当前情况。例如,人类的状态可以是名字、性别和肤色。
行为:对象可以执行的操作或方法。这些方法定义了对象如何与其他对象或数据交互。对象的状态改变必须通过调用方法实现。
标识:对象的唯一性,通过引用来区分不同的对象。每个对象都有一个唯一的标识,即使它们的状态相同。实际上是它在内存中的引用。
构造函数
构造器是一种特殊的方法,用来构造并初始化对象。构造器的名字应该与类名相同,在想要构造一个对象时,应在前面加一个new操作符
java"> Date birthday = new Date(); //构造了一个新对象。根据构造函数进行初始化。
java"> Date deadline; //虽然这句话定义了一个对象变量deadline,但是没有引用对象,不能调用类中的方法
deadline = new Date(); //这两种方法都能够对deadline进行初始化。
deadline = birthday; //变量引用一个已经存在的对象
一个对象变量并没有实际包含一个对象,仅仅是引用了一个对象。表达式new Date()构造了一个Date类型的对象,并且它的值是对新创建对象的引用,这个引用存储在变量deadline中。
-
用来初始化对象
-
构造器与类同名
-
每个类可以有一个以上的构造器
-
构造器可以0个或以上个参数
-
构造器没有返回值
-
构造器总是伴随着new操作一起调用
-
构造器可以调用其他方法
参数
隐式参数:在方法内部可以直接访问的对象的属性或状态,通常是指当前对象的实例变量。在实例方法中,可以通过 this
关键字来引用当前对象。
显式参数:在方法调用时明确传递给方法的参数。调用方法时,你需要在方法名后面的括号中直接提供这些参数。
java"> public void raiseSalary(double byPercent){ //显式
double raise = this.salary*byPercent/100;
this.salary += raise; //隐式
}
封装
封装的主要目的是隐藏类的内部实现细节,只向外部提供必要的接口,从而保护对象的状态和数据完整性。通过这种方式,外部代码无法直接访问对象的内部状态,只能通过公共方法与之交互。属性设置为私有。
类中要提供以下三点:
-
私有的数据域
-
共有的域访问器(get方法)
-
共有的域更改器(set方法)
java"> class People{
private String name;
public String getname(){
return name;
}
public void setname(String name){
this.name = name; //this是为了避免混淆,如果我传参设置为String n,那么这句话可以直接name = n;
}
}
final 实例域
可以将实例域定义为final,构建对象时必须初始化这样的域,并且在后面的操作中,不能够再对它进行修改。
final大多应用于最基本的类型域或者不可变的域。eg:身份证号
静态域和静态方法
静态域:属于类而不是类的实例。所有实例共享同一个静态域。被称为类域。
静态方法:属于类而不是实例。可以在没有对象实例的情况下调用,最常见的时main方法。一种不能向对象实施操作的方法,可以认为静态方法是没有this参数的方法。
java">//静态变量,实际并不常用。
public class Counter {
static int count = 0; // 静态变量
public Counter() {
count++; // 每次创建一个新对象时,count 增加 1
}
public static void displayCount() {
System.out.println("Current count: " + count);
}
}
public class Main {
public static void main(String[] args) {
Counter c1 = new Counter(); // count = 1
Counter c2 = new Counter(); // count = 2
Counter c3 = new Counter(); // count = 3
Counter.displayCount(); // 输出: Current count: 3
}
}
java"> public class MathUtils {
static int add(int a, int b) {
return a + b; // 静态方法
}
}
public class Main {
public static void main(String[] args) {
int sum = MathUtils.add(5, 10); // 直接通过类名调用静态方法,没有new
System.out.println("Sum: " + sum); // 输出: Sum: 15
}
}
实际应用中,对于静态常量的应用比较多,应为其能够共享的特点,可以直接使用。
java"> public class Math{
public static final double PI = 3.141592....; //我省略了,不敲了
}
Math.PI
对象构造
重载
重载:如果多个方法有相同的名字、不同的参数便产生了重载。
例如:有些类有多个构造器。
java"> public class MathUtils {
// 重载方法:两个整数相加
public int add(int a, int b) {
return a + b;
}
// 重载方法:三个整数相加
public int add(int a, int b, int c) {
return a + b + c;
}
// 重载方法:两个浮点数相加
public double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
MathUtils mathUtils = new MathUtils();
// 调用不同的重载方法
int sum1 = mathUtils.add(5, 10); // 调用两个整数相加
int sum2 = mathUtils.add(5, 10, 15); // 调用三个整数相加
double sum3 = mathUtils.add(5.5, 10.5); // 调用两个浮点数相加
System.out.println("Sum of two integers: " + sum1); // 输出: Sum of two integers: 15
System.out.println("Sum of three integers: " + sum2); // 输出: Sum of three integers: 30
System.out.println("Sum of two doubles: " + sum3); // 输出: Sum of two doubles: 16.0
}
}
默认初始化
如果构造器中没有显示的给域赋值,那么会自动的赋为默认值:0、false、null。
无参数构造器
如果没有写构造器,编译器会为你提供一个无参构造器。
如果写了构造器,但是没有写无参构造器,那么在构造对象时如果没有提供参数就是为不合法。
显示域初始化
java">//第一种:直接赋值
private String name = "";
//第二种:调用方法
private int id = assignId();
private static int assignId(){
int r = nextId;
nexId++;
return r;
}
调用另一个构造器
关键字this引用方法的隐式参数。还有另外一个功能,如果构造器的第一个语句形如this(...),这个构造器将调用同一个类中的另一个构造器。
java">public Employee(double s){
this("Employee", s);
}
public Employee(String n, double s){
//...
}
初始化块
-
在构造器中设置值
-
在声明中赋值
-
初始化块
java">class Employee{
private static int nextId;
private int id;
//初始化块
{
id = nextId;
nextId++;
}
}
抽象类
允许程序员通过隐藏复杂性和只暴露必要的部分来简化系统的设计和实现。抽象的主要目的是让程序员能够专注于对象的本质特征,而不是其具体实现细节。
-
抽象类是一个不能被实例化的类,可以包含抽象方法(没有实现)和具体方法(有实现)。
-
抽象方法必须在其子类中被实现。
-
抽象类通常用于定义一组相关类的公共接口和基本功能。
使用场景:
-
当多个类有共同的行为和属性,但具体实现可能不同时,使用抽象类。
-
当您希望定义一个协议,多个类都必须遵循时,使用接口。
java">abstract class Animal {
abstract void sound(); // 抽象方法
void sleep() { // 具体方法
System.out.println("Sleeping...");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Bark");
}
}
接口是一种完全抽象的类,所有方法都是抽象的。
java">interface Animal {
void sound(); // 抽象方法
}
class Cat implements Animal {
public void sound() {
System.out.println("Meow");
}
}