目录
OOP介绍
类和对象
方法参数
静态
包和import
构造方法
多态
访问权限
内部类
抽象
接口
枚举
匿名类
bean类
作用域
Java 是一种面向对象的编程语言,面向对象编程(Object-Oriented Programming,简称 OOP)是一种程序设计思想,它将现实世界中的事物抽象为对象,通过封装、继承和多态等特性来描述对象之间的关系和交互。
面向对象编程的三大特性是:
封装(Encapsulation):指隐藏对象的内部状态,并且通过公共接口对外提供访问方式。这样可以保证对象的内部状态不被外部改变,同时也方便了对象的使用。
继承(Inheritance):指子类继承父类的属性和方法。子类可以重写父类的方法,或者增加自己的方法和属性,从而实现代码的复用和扩展。
多态(Polymorphism):指同一种操作作用于不同的对象上会产生不同的效果。多态可以通过方法的重载和重写实现。
通过类和对象的概念,我们可以将代码组织成易于管理和重用的模块化结构。这种面向对象的编程范式是 Java 编程的核心。
1、类(Class): 类是用来描述一类具有相同属性和行为的对象的抽象概念。它是创建对象的模板或蓝图。
在 Java 中,可以使用 class
关键字来定义一个类。以下是一个简单的类的示例:
public class Person {
// 属性
private String name;
private int age;
// 构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 方法
public void sayHello() {
System.out.println("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
}
}
2、对象(Object): 对象是类的一个实例,它拥有类定义的属性和方法。通过创建对象,我们可以使用类中定义的方法和访问类的属性。
new
关键字来创建一个对象,通过调用类的构造方法对对象进行初始化。以下是使用上述类创建对象并访问属性和方法的示例:
// 创建对象
Person person = new Person("Alice", 25);
// 访问属性
System.out.println(person.name); // 输出:Alice
System.out.println(person.age); // 输出:25
// 调用方法
person.sayHello(); // 输出:Hello, my name is Alice and I am 25 years old.
方法参数是用于接收传递给方法的值或引用的变量。通过方法参数,我们可以将数据传递给方法,并在方法内部进行处理。Java 中的方法参数有两种类型:基本数据类型和引用数据类型。
1、基本数据类型参数: 基本数据类型参数是传递给方法的值的副本。这意味着,在方法内部对参数进行修改不会影响原始的变量。
2、引用数据类型参数(包括字符串、数组、类、接口、枚举、包装类、映射、集合): 引用数据类型参数是传递给方法的引用,这意味着在方法内部对参数进行修改会影响原始的对象。
静态是面向对象编程中的一个关键字,用于修饰类、方法和变量。静态成员与特定的对象实例无关,而是与类本身相关联。
1、静态变量: 静态变量属于类,而不属于类的任何特定实例。它们在类加载时被初始化,并且只有一个副本存在于内存中。静态变量可以通过类名直接访问,无需创建对象实例。
2、静态方法: 静态方法属于类,而不属于类的任何特定实例。它们在类加载时就存在于内存中,可以通过类名直接调用,无需创建对象实例。静态方法只能访问静态成员变量和其他静态方法,不能访问非静态成员变量和方法。
3、静态代码块:一种特殊的代码块,用于在类加载时执行一些初始化操作,对静态变量进行赋值或执行其他静态操作。它只会执行一次,并且在类的所有实例对象之前执行。
1、包的定义: 在 Java 中,包的定义使用关键字 package
,位于源代码文件的开头。包名采用小写字母,多个单词之间使用点(.)分隔。
package com.example.mypackage;
2、导入类: 当我们需要在一个类中使用另一个包中的类时,我们可以使用 import
关键字将其导入。导入可以是针对单个类的,也可以是针对整个包的。
import com.example.otherpackage.SomeClass;
import java.util.*;
3、使用导入的类: 一旦我们导入了某个类或者整个包,就可以直接在代码中使用它们,无需使用包名限定。(如果我们没有导入某个类,而又想使用它,就必须使用完整的包名限定。)
import com.example.otherpackage.SomeClass;
public class MyClass {
public static void main(String[] args) {
SomeClass obj = new SomeClass();
// 使用 SomeClass 类
}
}
构造方法(Constructor)是一种特殊的方法,用于创建和初始化对象。它负责在对象创建时为对象的成员变量赋初值,并执行其他必要的初始化操作。构造方法具有以下特点:
构造方法在以下情况下被调用:
new
关键字创建对象时,会调用相应类的构造方法。
多态是面向对象编程的一个重要概念。它允许我们使用父类类型的引用来引用子类对象,以一种统一的方式处理不同类型的对象。
多态有以下几个关键点:
父类类型 引用变量 = new 子类类型()
。这样做的好处是,我们可以通过父类的引用调用子类中重写的方法,实现多态的效果。访问权限修饰符可以控制类、接口、方法或变量对外部的可见性,是实现封装性的重要手段。
在 Java 面向对象编程中,有四种访问权限修饰符:public、protected、default(package-private)、private。这四种访问权限修饰符的作用范围如下:
在 Java 中,内部类是定义在其他类内部的类。它允许在一个类的内部创建另一个类,这样可以更好地组织和封装代码。内部类主要有以下几种类型:
成员内部类:成员内部类是定义在另一个类内部的普通类。它与外部类之间存在一个包含关系,可以访问外部类的成员变量和方法(包括私有成员),并且可以使用外部类的引用来访问外部类的实例。成员内部类可以被私有化,只有外部类可以访问它。
静态内部类:静态内部类是定义在其他类内部的静态类。它与外部类之间没有包含关系,可以直接通过外部类的类名访问,无需创建外部类的实例。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。
方法内部类:方法内部类是定义在方法内部的类。它的作用域限定在方法内部,只能在方法内部创建该类的实例。方法内部类可以访问外部类的成员变量和方法,但只能访问 final 或 effectively final 的局部变量。
匿名内部类:匿名内部类是没有类名的内部类,它通常用于创建一个只需要使用一次的类。匿名内部类必须继承一个父类或实现一个接口,并且可以在创建对象的同时定义类的实现。由于没有类名,所以无法在其他地方再次使用。
使用内部类可以实现以下几个优点:
在 Java 面向对象编程中,抽象是一种重要的概念。抽象是指将问题的本质特征提取出来,忽略掉与问题无关的细节,从而将问题简化为更易于理解和处理的形式。
在 Java 中,可以通过以下方式实现抽象:
抽象类(Abstract Class):抽象类是用 abstract
关键字声明的类,它不能被实例化。抽象类可以包含抽象方法和非抽象方法。抽象方法是没有具体实现的方法,只有方法的声明,而具体的实现需要在子类中完成。子类必须实现抽象类中的所有抽象方法,否则子类也必须声明为抽象类。
抽象方法(Abstract Method):抽象方法是用 abstract
关键字声明的方法,它没有具体的实现,只有方法的声明。抽象方法必须声明在抽象类中。子类必须实现抽象类中的所有抽象方法,否则子类也必须声明为抽象类。
使用抽象类和抽象方法可以实现以下几个目的:
封装共性:抽象类可以定义一组相关的方法,并将它们封装在一个类中,从而提高代码的复用性和可维护性。
规范行为:抽象类可以定义一组抽象方法,规定子类必须实现的方法,从而强制子类按照规范进行行为的实现。
隐藏细节:通过将对象的共性特征抽象出来,可以隐藏对象的具体实现细节,使得代码更加简洁和易懂。
举例:
abstract class Animal {
public abstract void sound();
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound();
Animal cat = new Cat();
cat.sound();
}
}
在 Java 面向对象编程中,接口是一种定义了一组方法规范的抽象类型。接口可以被类实现(implement),从而使得类能够具备接口所定义的行为。接口类似于契约或协议,它规定了类必须实现的方法以及方法的签名,但不提供具体的实现。
在 Java 中,可以通过以下方式定义接口:
public interface InterfaceName {
// 声明方法,不包含方法体
void methodName();
int anotherMethod();
// ...
}
接口中的方法默认为抽象方法,不需要使用 abstract
关键字来声明。接口还可以包含常量和默认方法。
类可以通过关键字 implements
来实现一个或多个接口,并提供接口中方法的具体实现。一个类可以同时实现多个接口,从而具备多个接口所定义的行为。
下面是一个简单的示例,展示了接口的使用:
interface Animal {
void sound(); // 声明抽象方法
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
class Cat implements Animal {
@Override
public void sound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound();
Animal cat = new Cat();
cat.sound();
}
}
在 Java 中,枚举(Enum)是一种特殊的数据类型,用于定义一组有限的常量。枚举常量是预定义的、唯一的,并且在枚举类型中以逗号分隔列出。
使用枚举可以提供更加清晰和可读性强的代码,使得代码更具可维护性和可扩展性。Java 提供了关键字 enum
来定义一个枚举类型。
下面是一个简单的示例,展示了枚举的使用:
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
public class Main {
public static void main(String[] args) {
Day today = Day.TUESDAY;
System.out.println("Today is " + today);
}
}
枚举类型可以具有方法、构造函数和字段,就像一个普通的类一样。枚举常量也可以附加额外的数据和行为。
下面是一个带有方法和字段的枚举的示例:
enum Color {
RED("#FF0000"),
GREEN("#00FF00"),
BLUE("#0000FF");
private String hexCode; // 字段
Color(String hexCode) {
this.hexCode = hexCode;
}
public String getHexCode() { // 方法
return hexCode;
}
}
public class Main {
public static void main(String[] args) {
Color red = Color.RED;
System.out.println("Red color's hex code is " + red.getHexCode());
}
}
在 Java 中,匿名类是一种特殊的类,它没有显式的名称,通常用于创建一个只需要使用一次的类的实例。匿名类可以理解为是一个局部类,但是它的定义方式更加简洁。
匿名类可以在实例化对象的时候直接定义,而无需提前定义该类的名称。在创建匿名类的同时,也可以实现该类的接口或继承某个父类,从而利用其行为和属性。
下面是一个匿名类的示例,它继承了 Thread
类并覆盖了 run()
方法:
Thread thread = new Thread() {
@Override
public void run() {
System.out.println("Hello from anonymous class!");
}
};
thread.start();
在 Java 中,Bean 是一种特殊的类,它符合以下约定:
举例:
public class Person implements Serializable {
private String name;
private int age;
public Person() {}
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;
}
}
在 Java 中,作用域指的是变量的生命周期和可见性范围。Java 支持四种不同的作用域:
类级别作用域(static):由 static
修饰的变量或方法属于类级别作用域,可以通过类名访问。这些变量和方法在程序运行期间只会被创建一次,并且在整个程序执行期间都可以访问。
实例级别作用域:没有被 static
修饰的变量属于实例级别作用域,它们必须在实例化对象后才能被访问。每个实例都有一份独立的实例变量,它们在对象创建时被初始化,在对象销毁时被回收。
局部作用域:在方法、循环或语句块中定义的变量属于局部作用域,它们只能在所定义的代码块中访问,离开该代码块后就会被销毁。局部变量必须显式地初始化,否则编译器会报错。
匿名作用域:匿名作用域是指在内部类中定义的变量,它们通常用于解决内部类与外部类之间的数据共享问题。匿名变量的生命周期和内部类相同,离开内部类后就被销毁。