细究Java三大特性之封装、继承、多态
Java SE基础
文章目录
- Java SE基础
- 1. Java特性和优势
- 2. Java的三大版本
- 3. JDK、JRE、JVM三者关系
- JDK(Java Development Kit,Java开发者工具包)
- JRE(Java Runtime Environment,Java运行时环境)
- JVM(Java Virtual Machine,Java虚拟机)
- 4.Java 三大特性以及其JavaSE重要基础知识
- 4.1.封装
- 4.1.1封装的好处
- 4.2.继承
- 4.2.1概念
- 4.2.2 super讲解
- 4.2.2.1super的主要用法
- 4.2.3 方法重写
- 1.实现子类的特定行为:
- 2.支持多态性:
- 4.3.多态
- 4.3.1 多态定义
- 4.3.11.多态性的体现
- 4.3.2.2.代码的通用性和可扩展性
- 4.3.2多态的注意事项
1. Java特性和优势
Java作为一种广泛使用的编程语言,拥有以下特性和优势:
- 简单性:Java的语法设计简洁明了,易于学习和使用。它去除了C++中的一些复杂特性,例如指针操作和多重继承,使得开发者能够更专注于逻辑实现。
- 可移植性(不限平台):Java通过“一次编写,到处运行”(Write Once, Run Anywhere)的理念实现了跨平台特性。只要目标设备支持Java虚拟机(JVM),Java程序无需修改即可运行。
- 动态性(反射):Java支持运行时反射机制,允许程序在运行时动态检查类、方法和属性,甚至修改自身行为。这种特性在框架开发(如Spring)中尤为重要。
- 分布式:Java内置了对网络编程的支持(如Socket、RMI等),使得开发分布式应用程序(如跨服务器通信的系统)更加简单和高效。
- 多线程:Java提供了强大的多线程支持,开发者可以通过线程类或Runnable接口轻松实现并发任务,提高程序的执行效率。
- 面向对象:Java是一种纯粹的面向对象语言,支持封装、继承和多态等特性,有助于编写结构化、可重用的代码。
- 健壮性:Java通过强类型检查、异常处理机制和自动垃圾回收功能,减少了程序出错的可能性,提高了代码的稳定性。
- 安全性:Java内置了多层次的安全机制,例如字节码验证、类加载器和安全管理器,有效防止恶意代码的执行。
2. Java的三大版本
Java根据应用场景的不同,分为以下三大版本:
- **Java SE(Standard Edition,标准版)**这是Java的核心版本,主要用于开发桌面应用程序(如Swing界面程序)、控制台应用程序以及简单的服务器程序。它包含了Java的基础API和功能,是其他版本的基础。
- **Java ME(Micro Edition,微型版)**专为资源受限的嵌入式设备设计,例如早期功能手机、PDA以及小型家电。它是Java SE的精简版,适用于低功耗、低内存的场景。
- **Java EE(Enterprise Edition,企业版)**企业版基于Java SE扩展,专注于大规模、分布式、多层的企业级应用开发。它提供了丰富的API(如Servlet、JSP、EJB等),广泛用于Web开发、服务器端应用和企业系统。
3. JDK、JRE、JVM三者关系
这三个是Java生态系统中不可或缺的组成部分,以下是它们的详细解释:
JDK(Java Development Kit,Java开发者工具包)
JDK是面向开发者的完整工具集,包含了编写、编译和调试Java程序所需的一切。它包括:
- 编译器(javac):将Java源代码编译为字节码。
- Java API:提供丰富的类库供开发者调用。
- 调试工具和其他实用程序。 JDK还包含了JRE,因此安装JDK后即可运行Java程序。
JRE(Java Runtime Environment,Java运行时环境)
JRE是运行Java程序的最小环境,适合只需要执行Java应用而无需开发的普通用户。它包括:
- Java虚拟机(JVM):负责执行字节码。
- Java核心类库:提供运行时所需的基本功能(如I/O、集合框架等)。
- Java命令行工具(如java命令)。 JRE不包含开发工具,因此无法编译Java代码。
JVM(Java Virtual Machine,Java虚拟机)
JVM是Java跨平台特性的核心。它是一个虚拟化的运行环境,负责:
- 将Java字节码(.class文件)解释或编译为本地机器码。
- 管理内存(包括垃圾回收)。
- 提供硬件和操作系统的抽象层。 每个Java程序运行时都会启动一个JVM实例。
如下图清晰展示三者的关系:
4.Java 三大特性以及其JavaSE重要基础知识
4.1.封装
口诀:【 属性私有:get/set】。当我们需要获取元素时,使用get/set方法获取元素。
属性内可添加对数据添加的要求。
样例代码:
import java.util.*;
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String name = sc.nextLine();int age = sc.nextInt();Person xiaoming = new Person();xiaoming.setName(name);xiaoming.setAge(age);xiaoming.study();}}
public class Person {private String name;private int age;Person() {}//无参构造方法Person(String name,int age) {this.name = name;this.age = age;}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|| age>100) {System.out.println("您输入的年龄有误");}else {this.age = age;}}public void study () {System.out.println(this.name+" is studying ");}
}
在此案例中,我们将name与age私有后,就需要通过get/set方法修改或获取name/age元素
4.1.1封装的好处
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.提高系统可维护性
4.2.继承
4.2.1概念
使用关键字:
extends
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。在java只有单继承,没有多继承。在java中,所有类继承与Object类
4.2.2 super讲解
简单来说,super的作用即是调用或引用父类。
使用注意点:
- 调用父类的构造方法;
- 必须只能出现在子类的方法或者构造方法中;
- super和this 不能同时调用构造方法;
- 在子类的无参方法中,系统自动调用父类的无参构造方法 ;
4.2.2.1super的主要用法
-
访问父类的成员变量
使用
super
关键字可以在子类中访问父类中的成员变量。这对于在子类中有相同名字的成员变量时很有用,以便明确指定你想要访问的是父类的成员变量。package com.sky.test;class Parent {int x = 10; }class Child extends Parent {int x = 20;void display() {System.out.println(super.x); // 访问父类的x变量 10 System.out.println(this.x); // 访问子类的x变量 20} }public class Main {public static void main(String[] args) {Child child = new Child();child.display();} }
-
调用父类中的构造方法
在子类的构造函数中使用
super
关键字可以调用父类的构造函数。这通常用于初始化父类的成员变量或执行父类构造函数的逻辑。经常用在下面这种情况,类中有些变量是子类继承父类的 利用super可调用父类的构造方法将其赋值
代码案例:
class Parent {int x;Parent(int x) {this.x = x;}
}class Child extends Parent {int y;Child(int x, int y) {super(x); // 调用父类构造函数 将x赋值this.y = y;}// @Override 不理解也没事,不带上这个注解一样能正常运行@Override // java中的注解 此处的意思是表明此方法是重写过的方法public String toString() { // 返回带上child的成员变量值的字符串 x和yreturn "Child{" +"y=" + y +", x=" + x +'}';}
}public class Main {public static void main(String[] args) {Child child = new Child(10, 20);System.out.println(child.toString());}
}
-
调用父类中的方法
使用 super
关键字可以在子类中显式调用父类的方法。这在子类重写父类的方法时特别有用,以便在子类中可以调用父类的版本。
代码案例:
class Parent {void print() {System.out.println("Parent's print method");}
}class Child extends Parent {@Overridevoid print() {super.print(); // 调用父类的print方法System.out.println("Child's print method");}
}public class Main {public static void main(String[] args) {Child child = new Child();child.print();}
}
4.2.3 方法重写
重写条件:需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大 :public>protected>default>private
- 抛出的异常:范围,可以被缩小,但不能扩大
思考:为什么需要重写?
1.实现子类的特定行为:
父类定义的方法可能只提供通用的实现,但子类需要根据自己的特性提供特定的实现。通过重写方法,子类可以覆盖父类的方法逻辑,以适应自己的需求。
class Animal {void sound() {System.out.println("Some generic animal sound");}
}class Dog extends Animal {@Overridevoid sound() {System.out.println("Woof"); // 子类提供具体实现}
}
2.支持多态性:
重写方法允许在运行时根据对象的实际类型调用相应的方法实现(动态绑定)。这使得代码更灵活,可以通过父类引用调用子类的特定行为。
Animal myDog = new Dog();
myDog.sound(); // 输出 "Woof",调用的是Dog的重写方法
4.3.多态
4.3.1 多态定义
同一方法可以根据发送对象的不同而采用多种不同的行为方式
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
若方法被子类重写,则执行子类的方法
例如,下面的案例是根据猫和狗叫的动作的不同,而实现的多态:
class Animal {public void sound() {System.out.println("动物发出声音");}
}class Dog extends Animal {@Overridepublic void sound() {System.out.println("狗发出汪汪声");}
}class Cat extends Animal {@Overridepublic 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(); // 输出:猫发出喵喵声}
}
在这个示例中,Animal
类是父类,Dog
和 Cat
类是它的子类。通过将父类的引用变量分别指向子类对象,实现了多态性。在运行时,根据引用变量的实际类型来调用相应的子类方法,从而输出不同的声音。
思考:为什么使用 Animal animal1 = new Dog() 而不是 Dog dog = new Dog()
是为了利用 多态性(Polymorphism)的特性。以下是具体原因和分析:
4.3.11.多态性的体现
当你使用父类引用(Animal)指向子类对象(Dog 或 Cat)时,Java 在运行时会根据对象的实际类型(Dog 或 Cat)调用对应的重写方法**(sound())**。这种行为称为 动态绑定 或 运行时多态。
Animal animal1 = new Dog();
animal1.sound(); // 输出 "狗发出汪汪声",调用的是 Dog 类的 sound 方法
这里,animal1 是 Animal 类型的引用,但实际对象是 Dog,因此运行时会调用 Dog 的 sound() 方法。
- 如果直接使用 **Dog dog = new Dog(),**虽然也能调用 dog.sound() 得到相同的结果,但你失去了多态的灵活性,因为 dog 只能引用 Dog 类型的对象,无法引用其他子类(如 Cat)。
4.3.2.2.代码的通用性和可扩展性
使用父类引用(如 Animal)可以让代码更通用,适用于处理多种子类对象。例如,你可以将 Dog 和 Cat 放入一个 Animal 类型的数组或集合中:
Animal[] animals = {new Dog(), new Cat()};
for (Animal animal : animals) {animal.sound(); // 自动调用对应子类的 sound 方法
}
这允许你以统一的方式处理不同类型的子类对象,而无需为每种子类写单独的代码。如果用 Dog dog = new Dog(),你就只能处理 Dog 类型的对象,无法直接处理 Cat 或其他 Animal 的子类,代码的灵活性和可扩展性会降低。
4.3.2多态的注意事项
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系,必要时需要类型转换
包含以下关键字无法被重写的方法:
-
static
-
final
-
private
这就是JavaSE中三大特性的基本介绍,包含用法和注意事项,笔者编写不易,如果您有任何想法,或者文章中哪里有不足的地方,欢迎评论区交流!!!