enyang
enyang
Published on 2025-01-07 / 49 Visits
0
0

Java特性与关键术语

1. 三大特性

1.1 封装

Java 的封装特性是面向对象编程(OOP)的核心之一,其核心理念是将数据(属性)和操作这些数据的方法(行为)封装在一个类中,并通过访问控制限制对数据的直接访问,确保对象的内部状态受到保护。

1.1.1 封装核心概念

数据隐藏(Data Hiding)

通过将类的属性声明为 private,限制外部直接访问。提供 public 的方法(如 getter 和 setter)来控制对属性的访问和修改。隐藏对象内部实现细节,仅暴露必要的接口,提升代码安全性和灵活性。

访问控制(Access control)

使用访问修饰符控制类成员的可见性。private:仅在类内部可访问。protected:在类内部及子类、同一包中可访问。public:对所有类都可访问。默认(包访问权限):仅在同一包内可访问。

只暴露必要的功能

提供明确的接口,防止外部随意修改类的内部实现。通过方法限制对数据的非法或不合理操作。

1.1.2 封装的实现步骤

1. 将类的属性设为private。

2. 提供 public 的 getter 和 setter 方法,用于读取和修改属性值。

3. 在 setter 方法中加入数据验证逻辑,确保数据的有效性。

示例代码

public class Person {
    // 私有属性
    private String name;
    private int age;

    // 公共的 getter 方法
    public String getName() {
        return name;
    }

    // 公共的 setter 方法
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    // 在 setter 中添加数据校验
    public void setAge(int age) {
        if (age >= 0 && age <= 150) {
            this.age = age;
        } else {
            System.out.println("年龄必须在 0 到 150 之间");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("Fiona");
        person.setAge(22);

        System.out.println("姓名: " + person.getName());
        System.out.println("年龄: " + person.getAge());

        // 尝试设置非法年龄
        person.setAge(-5); // 输出:年龄必须在 0 到 150 之间
    }
}

1.1.3 封装的优点

①数据安全性

• 防止外部代码直接访问或修改对象的私有属性。

• 提供验证机制(如 setter 方法)以确保数据的有效性。

②代码灵活性

• 对象的内部实现可以随时更改,而不影响外部代码。

• 用户通过公共接口与对象交互,减少对具体实现的依赖。

③提高可维护性

• 将属性和行为绑定在一个类中,逻辑清晰,易于维护。

④模块化

• 每个类封装自己的数据和逻辑,减少代码之间的耦合性。

1.1.4 封装中的注意事项

①适当的访问权限控制

• 并非所有属性都需要设置为 private,根据实际情况决定访问级别。

②滥用 getter 和 setter

•不要将所有属性都直接暴露给外界。

• 考虑是否需要对属性添加访问限制或业务逻辑。

③组合封装与继承

• 封装和继承需要配合使用,避免将所有细节暴露给子类。

封装通过隐藏内部实现细节并仅暴露必要的接口,提高了数据的安全性、代码的灵活性和可维护性。在 Java 中,封装主要通过 private 关键字、getter 和 setter 方法以及访问控制修饰符实现。

1.2 继承

Java 的继承特性是面向对象编程(OOP)的核心概念之一,它允许一个类从另一个类继承属性和方法,从而实现代码的重用和扩展。

1.2.1 继承的定义

继承是指一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。

• 关键词:extends

• 子类不仅能继承父类的所有非私有属性和方法,还可以重写或新增方法以实现自己的特性。

示例代码

// 父类
class Animal {
    String name;

    void eat() {
        System.out.println(name + " is eating.");
    }

    void sleep() {
        System.out.println(name + " is sleeping.");
    }
}

// 子类
class Cat extends Animal {
    void play() {
        System.out.println(name + " is playing.");
    }
}

public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "MiMi";
        cat.eat();  // 从父类继承的方法
        cat.sleep(); // 从父类继承的方法
        cat.play();  // 子类自己的方法
    }
}

输出

MiMi is eating.
MiMi is sleeping.
MiMi is playing.

1.2.2 继承的关键特性

①单继承

• Java 中的类只支持单继承,一个类只能继承一个父类。

• 例如:class Child extends Parent

super 关键字

• 用于调用父类的构造方法或方法。

• 可以显式调用父类的属性或方法,避免子类覆盖的方法干扰。

示例代码

class Animal {
    void eat() {
        System.out.println("Animal is eating.");
    }
}

class Dog extends Animal {
    void eat() {
        System.out.println("Dog is eating.");
    }

    void callParentEat() {
        super.eat(); // 调用父类的方法
    }
}

③构造器的继承

• 子类的构造方法默认会调用父类的无参构造方法。

• 如果父类没有无参构造方法,子类必须显式调用父类的有参构造方法。

④方法重写(Overriding)

• 子类可以重写父类的方法以实现自己的行为。

• 重写的方法需具有相同的名称、返回值类型和参数列表。

@Override 注解用于标识重写,便于编译器检查。

⑤继承的访问控制

• 子类可以访问父类的 publicprotected 成员,不能直接访问 private 成员。

• 如果子类和父类在同一包中,还可以访问默认成员(包访问权限)。

⑥最终类与方法

• 使用 final 关键字修饰的类不能被继承。

• 使用 final 修饰的方法不能被子类重写。

1.2.3 继承的优点

①代码复用性

• 子类可以直接复用父类的代码,无需重复编写相同逻辑。

②代码扩展性

• 子类可以在父类的基础上扩展新功能。

③提高维护性

• 通过继承实现公共功能的抽象,使代码更易于维护。

④实现多态

• 父类引用可以指向子类对象,从而实现动态绑定。

1.2.4 继承的限制与注意事项

①单继承限制

• Java 不支持多继承,但可以通过实现多个接口来实现类似效果。

②父类的依赖

• 子类的实现依赖于父类,可能会导致父类修改时对子类产生较大影响。

③构造器调用限制

• 子类的构造方法必须调用父类的构造方法,且必须是第一行代码。

④过度继承问题

• 继承层次过深可能导致代码难以理解和维护。

• 可以考虑使用组合(Composition)代替继承。

1.2.5 继承与组合的比较

特性

继承

组合

代码复用性

耦合性

强(子类依赖于父类)

弱(通过对象关联)

灵活性

子类必须继承父类全部行为

组合可以选择性使用对象的行为

使用场景

需要 “is-a” 关系时适用

需要 “has-a” 关系时适用

示例:继承与多态的结合

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal; // 父类引用
        myAnimal = new Dog(); // 子类对象
        myAnimal.sound(); // 输出:Dog barks

        myAnimal = new Cat(); // 子类对象
        myAnimal.sound(); // 输出:Cat meows
    }
}

继承是 Java 的三大特性之一,它允许子类重用父类的代码,同时支持方法重写和多态特性。虽然继承提高了代码复用性和扩展性,但也需要注意合理设计继承层次,避免产生过强的耦合和维护成本过高的问题。在实际开发中,可以根据需求选择继承或组合实现代码复用和扩展。

1.3 多态

多态(Polymorphism)是面向对象编程(OOP)的三大特性之一,指同一个接口在不同对象中可以有不同的实现。多态可以提高代码的灵活性、可扩展性和可维护性。

1.3.1 多态的基本概念

①编译时多态(静态绑定)

• 通过方法重载(Method Overloading)实现。

• 方法的调用在编译时决定。

②运行时多态(动态绑定)

• 通过方法重写(Method Overriding)实现。

• 方法的调用在运行时根据实际对象类型决定。

1.3.2 编译时多态(方法重载)

• 同一个类中,方法名称相同,但参数列表不同(参数的个数或类型不同)。

• 编译器根据方法签名确定调用哪个方法。

示例代码:方法重载

class Calculator {
    // 重载方法:add
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        System.out.println(calculator.add(1, 2));           // 输出:3
        System.out.println(calculator.add(1.5, 2.5));       // 输出:4.0
        System.out.println(calculator.add(1, 2, 3));        // 输出:6
    }
}

1.3.3 运行时多态(方法重写)

• 定义:子类通过重写父类方法,实现不同的行为。

• 特点:必须有继承关系;使用父类引用指向子类对象;方法调用在运行时根据对象实际类型动态绑定。

示例代码:方法重写与多态

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal; // 父类引用

        myAnimal = new Dog(); // 指向 Dog 对象
        myAnimal.sound();     // 输出:Dog barks

        myAnimal = new Cat(); // 指向 Cat 对象
        myAnimal.sound();     // 输出:Cat meows
    }
}

1.3.4 多态的优点

①灵活性

• 可以针对父类编写通用代码,通过多态机制执行子类的特定实现。

②可扩展性

• 新增子类时,不需要修改父类代码,只需实现或重写方法。

③代码复用

• 可以重用父类代码,提高开发效率。

⑤接口统一性

• 不同子类实现相同接口,调用时不需关心具体实现。

1.3.5 多态的应用场景

①统一接口操作

• 通过父类引用或接口操作多种子类实例。

②抽象类和接口

• 定义一组行为规范,不同类可以根据需求实现这些行为。

示例:接口的多态

interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape; // 接口引用

        shape = new Circle();
        shape.draw(); // 输出:Drawing a Circle

        shape = new Rectangle();
        shape.draw(); // 输出:Drawing a Rectangle
    }
}

1.3.6 注意事项

①多态的前提

• 必须有继承关系。

• 必须有方法重写。

②父类引用只能调用父类定义的方法

• 即使子类有额外方法,父类引用也无法直接访问。

• 解决方案:类型转换。

Dog dog = new Dog();
Animal animal = dog;
((Dog) animal).bark(); // 调用 Dog 的特有方法

③静态方法和多态

• 静态方法不能被重写,因此不支持运行时多态。

④构造方法不支持多态

• 构造方法不能被继承,也不参与多态。

Java 的多态包括编译时多态(方法重载)和运行时多态(方法重写),是面向对象编程的核心特性之一。通过多态,代码可以具有更高的灵活性、可扩展性和可维护性,广泛应用于接口、抽象类、框架设计等场景。

2. 关键术语

2.1 简单性(Simplicity)

• Java 的语法简洁直观,去除了 C++ 中复杂的特性(如指针、多重继承、显式内存管理)。

• 更容易学习和使用,尤其对初学者友好。

2.2 面向对象(Object-Oriented)

• Java 是一种完全面向对象的编程语言,支持类、对象、继承、封装、多态和抽象等 OOP 特性。

• 一切操作围绕对象展开,提高代码的可重用性和可扩展性。

2.3 分布式(Distributed)

• Java 提供了对分布式计算的支持,可以使用网络协议(如 HTTP 和 FTP)实现分布式系统。

• 内置的 RMI(远程方法调用)EJB(企业 Java Bean) 等技术帮助开发分布式应用。

2.4 健壮性(Robustness)

• Java 提供了强大的内存管理机制(如垃圾回收器),减少了内存泄漏的可能性。

• 拥有异常处理机制(try-catch-finally),提高程序的容错性。

• 去除了指针操作,避免因指针错误导致的程序崩溃。

2.5 安全性(Security)

字节码验证器:确保字节码的安全性和合法性。

类加载器:防止恶意类的加载。

沙箱模型:限制未授权代码的执行范围。

• 被广泛用于网络和企业级应用的开发。

2.6 体系结构中立(Architecture-Neutral)

• Java 的编译器生成的字节码(.class 文件)与平台无关,可以在任何安装了 JVM 的平台上运行。

• 确保应用程序能够在不同硬件或操作系统上保持一致的行为。

2.7 可移植性(Portability)

• Java 应用程序只需编译一次,就可以在任何支持 JVM 的设备上运行(“一次编译,到处运行”)。

• 通过屏蔽平台的差异(如文件系统和内存管理)提高可移植性。

2.8 解释型(Interpreted)

• Java 的字节码由 JVM 解释执行,不需要重新编译。

• 提供即时编译(JIT)功能,进一步提升执行效率。

2.9 高性能(High Performance)

• Java 使用即时编译器(JIT)优化字节码的执行速度。

• 虽然比纯静态编译语言稍慢,但得益于改进的 JVM 和优化算法,Java 性能已接近原生代码。

2.10 多线程(Multithreading)

• Java 原生支持多线程,允许同时执行多个任务(如后台任务、用户界面操作等)。

• 提供了丰富的多线程 API,如 Thread 类和 Runnable 接口。

• 提升应用程序的并发性能,广泛用于服务器和高性能计算场景。

2.11 动态性(Dynamic)

• Java 支持动态加载类,允许在运行时决定需要加载的类和对象。

• 支持反射(Reflection),可以在运行时分析类、方法和字段。

• 动态绑定(Dynamic Binding)允许在运行时决定方法的调用,实现更高的灵活性。


Comment