【Java】小白友好的面向对象编程学习笔记

目录

OOP介绍

类和对象

方法参数

静态

包和import

构造方法

多态

访问权限

内部类

抽象

接口

枚举

匿名类

bean类

作用域


OOP介绍

Java 是一种面向对象的编程语言,面向对象编程(Object-Oriented Programming,简称 OOP)是一种程序设计思想,它将现实世界中的事物抽象为对象,通过封装、继承和多态等特性来描述对象之间的关系和交互。

面向对象编程的三大特性是:

  1. 封装(Encapsulation):指隐藏对象的内部状态,并且通过公共接口对外提供访问方式。这样可以保证对象的内部状态不被外部改变,同时也方便了对象的使用。

  2. 继承(Inheritance):指子类继承父类的属性和方法。子类可以重写父类的方法,或者增加自己的方法和属性,从而实现代码的复用和扩展。

  3. 多态(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、静态代码块:一种特殊的代码块,用于在类加载时执行一些初始化操作,对静态变量进行赋值或执行其他静态操作。它只会执行一次,并且在类的所有实例对象之前执行。

包和import

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)是一种特殊的方法,用于创建和初始化对象。它负责在对象创建时为对象的成员变量赋初值,并执行其他必要的初始化操作。构造方法具有以下特点:

  1. 构造方法的名称必须与类名相同。
  2. 构造方法没有返回类型,包括 void。
  3. 构造方法可以有参数,也可以没有参数。
  4. 如果没有定义构造方法,Java 会提供一个默认的无参构造方法,用于创建对象。

构造方法在以下情况下被调用:

  1. 在使用 new 关键字创建对象时,会调用相应类的构造方法。
  2. 在通过继承创建子类对象时,会先调用父类的构造方法,然后再调用子类的构造方法。

 

多态

多态是面向对象编程的一个重要概念。它允许我们使用父类类型的引用来引用子类对象,以一种统一的方式处理不同类型的对象。

多态有以下几个关键点:

  1. 继承关系:多态是建立在类之间的继承关系上的。子类继承了父类的属性和方法,同时还可以添加自己特有的属性和方法。
  2. 方法重写:子类可以重写父类的方法,即在子类中重新定义与父类中同名的方法。这样在通过父类的引用调用该方法时,实际上会执行子类中重写的方法。
  3. 父类引用指向子类对象:我们可以使用父类类型的引用来引用子类对象,例如 父类类型 引用变量 = new 子类类型()。这样做的好处是,我们可以通过父类的引用调用子类中重写的方法,实现多态的效果。
  4. 运行时绑定:Java的多态是在运行时确定的,而不是在编译时。也就是说,当调用一个方法时,实际执行的方法取决于对象的类型,而不是引用的类型。

访问权限

访问权限修饰符可以控制类、接口、方法或变量对外部的可见性,是实现封装性的重要手段。

在 Java 面向对象编程中,有四种访问权限修饰符:public、protected、default(package-private)、private。这四种访问权限修饰符的作用范围如下:

  1. public:表示公开的访问权限,可以被任何类、接口、方法或变量访问。
  2. protected:表示受保护的访问权限,可以被本类、同包内的类和子类访问。
  3. default(或称为 package-private):表示默认的访问权限,只能被同一个包内的类访问。
  4. private:表示私有的访问权限,只能被本类访问。

 

 

内部类

在 Java 中,内部类是定义在其他类内部的类。它允许在一个类的内部创建另一个类,这样可以更好地组织和封装代码。内部类主要有以下几种类型:

  1. 成员内部类:成员内部类是定义在另一个类内部的普通类。它与外部类之间存在一个包含关系,可以访问外部类的成员变量和方法(包括私有成员),并且可以使用外部类的引用来访问外部类的实例。成员内部类可以被私有化,只有外部类可以访问它。

  2. 静态内部类:静态内部类是定义在其他类内部的静态类。它与外部类之间没有包含关系,可以直接通过外部类的类名访问,无需创建外部类的实例。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。

  3. 方法内部类:方法内部类是定义在方法内部的类。它的作用域限定在方法内部,只能在方法内部创建该类的实例。方法内部类可以访问外部类的成员变量和方法,但只能访问 final 或 effectively final 的局部变量。

  4. 匿名内部类:匿名内部类是没有类名的内部类,它通常用于创建一个只需要使用一次的类。匿名内部类必须继承一个父类或实现一个接口,并且可以在创建对象的同时定义类的实现。由于没有类名,所以无法在其他地方再次使用。

使用内部类可以实现以下几个优点:

  1. 封装性:内部类可以访问外部类的私有成员,从而实现更好的封装性。
  2. 组织性:内部类可以将相关的类组织在一起,使代码更加清晰和结构化。
  3. 回调功能:匿名内部类常用于实现回调功能,可以简化代码的编写。

抽象

在 Java 面向对象编程中,抽象是一种重要的概念。抽象是指将问题的本质特征提取出来,忽略掉与问题无关的细节,从而将问题简化为更易于理解和处理的形式。

在 Java 中,可以通过以下方式实现抽象:

  1. 抽象类(Abstract Class):抽象类是用 abstract 关键字声明的类,它不能被实例化。抽象类可以包含抽象方法和非抽象方法。抽象方法是没有具体实现的方法,只有方法的声明,而具体的实现需要在子类中完成。子类必须实现抽象类中的所有抽象方法,否则子类也必须声明为抽象类。

  2. 抽象方法(Abstract Method):抽象方法是用 abstract 关键字声明的方法,它没有具体的实现,只有方法的声明。抽象方法必须声明在抽象类中。子类必须实现抽象类中的所有抽象方法,否则子类也必须声明为抽象类。

使用抽象类和抽象方法可以实现以下几个目的:

  1. 封装共性:抽象类可以定义一组相关的方法,并将它们封装在一个类中,从而提高代码的复用性和可维护性。

  2. 规范行为:抽象类可以定义一组抽象方法,规定子类必须实现的方法,从而强制子类按照规范进行行为的实现。

  3. 隐藏细节:通过将对象的共性特征抽象出来,可以隐藏对象的具体实现细节,使得代码更加简洁和易懂。

举例:

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();

bean类

在 Java 中,Bean 是一种特殊的类,它符合以下约定:

  • 公共无参构造函数:Bean 类必须提供一个公共的无参构造函数,否则在某些情况下会出现异常。
  • 私有属性:Bean 类的属性应该是私有的,并通过公共的 getter 和 setter 方法来访问和修改属性值。
  • 可序列化:Bean 类必须实现可序列化接口,以便可以将其状态保存到磁盘或通过网络发送。
  • 命名规范: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 支持四种不同的作用域:

  1. 类级别作用域(static):由 static 修饰的变量或方法属于类级别作用域,可以通过类名访问。这些变量和方法在程序运行期间只会被创建一次,并且在整个程序执行期间都可以访问。

  2. 实例级别作用域:没有被 static 修饰的变量属于实例级别作用域,它们必须在实例化对象后才能被访问。每个实例都有一份独立的实例变量,它们在对象创建时被初始化,在对象销毁时被回收。

  3. 局部作用域:在方法、循环或语句块中定义的变量属于局部作用域,它们只能在所定义的代码块中访问,离开该代码块后就会被销毁。局部变量必须显式地初始化,否则编译器会报错。

  4. 匿名作用域:匿名作用域是指在内部类中定义的变量,它们通常用于解决内部类与外部类之间的数据共享问题。匿名变量的生命周期和内部类相同,离开内部类后就被销毁。

你可能感兴趣的:(java,学习,笔记,OOP,面向对象编程)