当前位置: 首页 > article >正文

java面向对象的程序设计,封装、继承、多态

文章目录

  • 封装
  • 继承
    • super关键字
      • 访问父类的构造函数
      • 调用父类的实例方法
      • 访问父类的实例变量
  • 多态
    • 方法重载
    • 方法重写
    • 向上转型
  • 为什么封装、继承和多态很重要?


封装

封装的核心就是 数据私有化 + 公共方法访问

将对象的属性和方法结合在一起,并限制对其直接访问。通过封装,可以提高代码的安全性,防止外部代码直接访问和修饰对象的内部状态,同时,封装也使得代码更加模块化和易于维护,因为类的内部实现被隐藏起来,只需要关注类的公共接口。

特点:

  • 隐藏实现细节:通过封装,外部代码不需要知道对象内部的具体实现,能通过公开的接口与对象交互。
  • 提高代码的灵活性和可维护性:可以修改内部实现,而不影响外部使用的代码。
  • 数据保护:可以通过 getter 和 setter 控制属性的访问权限,进行必要的验证和处理。

示例:

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

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

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        } else {
            System.out.println("年龄必须为正数!");
        }
    }
}

在这个例子中,nameage 是私有属性,不能直接访问,而是通过公开的 getName()setName() 方法来访问和修改。

继承

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

子类可以调用父类的方法,但是父类不能调用子类的方法

特点:

  • 代码复用:子类可以继承父类的成员变量和方法,从而避免重复代码。
  • 扩展性:子类可以根据需要扩展父类的功能。
  • 父类和子类之间的关系:子类是父类的扩展,父类一般是更通用的概念,而子类则是具体的实现。

示例:

class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("狗叫:汪汪");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("猫叫:喵喵");
    }
}

在这个例子中,DogCat 都继承自 Animal 类,重写了 sound() 方法,实现了各自特有的行为。

super关键字

super 关键字在 Java 中用于访问父类的成员(方法、构造函数或字段)。它常用于以下几种情况:

  • 访问父类的构造函数
  • 调用父类的实例方法
  • 访问父类的实例变量

注意:

  • super(参数) 必须是构造方法的第一行,用于调用父类构造方法。
  • super.方法名() 调用父类方法,常用于子类重写方法时保留父类逻辑。
  • super.变量名 访问父类的变量,当子类有同名变量时使用。
  • super 不能用于 static 方法中,因为 super 依赖对象,而 static 属于类。

访问父类的构造函数

当子类需要调用父类的构造函数时,可以使用 super() 关键字。特别是在子类的构造函数中,如果没有显式调用父类构造函数,Java 编译器会默认调用父类的无参构造函数。如果父类没有无参构造函数,子类需要显式调用父类的带参构造函数。

示例:

class Animal {
    public Animal() {
        System.out.println("Animal 类的构造函数");
    }

    public Animal(String name) {
        System.out.println("Animal 类的构造函数,名称:" + name);
    }
}

class Dog extends Animal {
    public Dog() {
        super();  // 调用父类的构造函数
        System.out.println("Dog 类的构造函数");
    }

    public Dog(String name) {
        super(name);  // 调用父类的带参构造函数
        System.out.println("Dog 类的构造函数,名称:" + name);
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog1 = new Dog();          // 输出:Animal 类的构造函数,Dog 类的构造函数
        Dog dog2 = new Dog("Bulldog"); // 输出:Animal 类的构造函数,名称:Bulldog,Dog 类的构造函数,名称:Bulldog
    }
}

在这个例子中:

  • Dog 类的构造函数使用 super() 调用了父类 Animal 的构造函数。
  • super(name) 调用了父类带参构造函数。

调用父类的实例方法

如果子类重写了父类的方法,想要在子类中调用父类的版本,可以使用 super 来引用父类的方法。

示例:

class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        super.sound();  // 调用父类的 sound 方法
        System.out.println("狗叫:汪汪");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();  // 输出:动物发出声音,狗叫:汪汪
    }
}

在这个例子中:

  • Dog 类重写了 sound() 方法,但它通过 super.sound() 调用了父类 Animalsound() 方法,然后再输出“狗叫:汪汪”。

访问父类的实例变量

当子类和父类有相同名称的成员变量时,子类可以使用 super 来区分访问父类的成员变量。

示例:

class Animal {
    String name = "动物";
}

class Dog extends Animal {
    String name = "狗";

    public void printNames() {
        System.out.println("子类的 name: " + name);      // 输出:狗
        System.out.println("父类的 name: " + super.name); // 输出:动物
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.printNames();
    }
}

在这个例子中:

  • Dog 类有一个名为 name 的实例变量,它覆盖了父类 Animal 中的 name 变量。
  • 使用 super.name 可以访问父类 Animal 中的 name 变量,而 name 直接访问的是子类 Dog 的变量。

多态

多态是指同一个方法在不同的对象上可以有不同表现。在java中,多态主要通过方法重载(同一个类中方法名称相同但参数不同)和方法重写(父类与子类中的方法名称、参数相同)来实现。

特点:

  • 方法重载:同一个类中,方法名称相同,但参数列表(参数类型、数量、顺序)不同,返回值可以相同或不同
  • **方法重写:**子类可以重写父类的方法,实现不同的行为。方法重写是在继承的基础上实现的。
  • **向上转型:**通过父类引用指向子类对象,调用方法时会根据实际对象的类型决定调用哪个方法。

方法重载

示例:

class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

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

这里是方法重载,add 方法有多个版本,参数不同,返回类型也不同。

方法重写

示例:

class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("狗叫:汪汪");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog animal1 = new Dog();
        animal1.sound();  // 输出:狗叫:汪汪
    }
}

向上转型

示例:

class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("狗叫:汪汪");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("猫叫:喵喵");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

        animal1.sound();  // 输出:狗叫:汪汪
        animal2.sound();  // 输出:猫叫:喵喵
    }
}

在这个例子中,animal1animal2 都是 Animal 类型的引用,但它们分别指向 DogCat 类型的对象。当调用 sound() 方法时,程序根据实际的对象类型决定调用哪个 sound() 方法。

向上转型可以使用调用,父类中的方法(但执行子类重写的版本),不能调用子类新增的方法

为什么封装、继承和多态很重要?

  • 封装:使得对象的实现细节对外部隐藏,避免了外部对内部状态的直接修改,提高了代码的安全性和维护性。
  • 继承:提供了代码复用的机制,使得子类可以继承父类的功能,从而减少重复代码,并且可以在子类中扩展功能。
  • 多态:允许对象的行为在运行时发生改变,提高了代码的灵活性和可扩展性。特别是在使用面向接口编程时,多态可以让代码更加通用,减少耦合度。

http://www.kler.cn/a/536223.html

相关文章:

  • 二叉树实现(学习记录)
  • 如何在Docker中运行MySQL容器?
  • 网络面试题(第一部分)
  • E4982A,keysight是德科技台式LCR表
  • 哈希(Hashing)在 C++ STL 中的应用
  • 大模型实战篇之Deepseek二、一键部署DeepSeek-V3和DeepSeek-R1模型
  • 4. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--什么是微服务--微服务设计原则与最佳实践
  • MySQL主从复制原理及工作过程
  • [数据结构] Set的使用与注意事项
  • OpenBMC:可编译的硬件平台定义在哪
  • 安恒网安面试题来啦!
  • 模型压缩技术(一):模型蒸馏,给大模型“瘦身”
  • 软件设计模式
  • 自动化测试(selenium篇)
  • python怎么求 一个数是否包含3
  • WPF模板
  • Python应用指南:一个库解决常见的国内坐标系转换需求
  • 工厂模式+枚举类的json序列化+redisson的使用
  • 【深度学习】DataLoader自定义数据集制作
  • 海康威视豆干型网络相机QT的Demo
  • 【学习总结|DAY036】Vue工程化+ElementPlus
  • 华为小艺助手接入DeepSeek,升级鸿蒙HarmonyOS NEXT即可体验
  • Linux中DataX使用第三期
  • Java 8的Stream API
  • 栈和队列的实现(C语言)
  • 解决aspose将Excel转成PDF中文变成方框的乱码问题