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

word做网站连接免费软件漫画

word做网站连接,免费软件漫画,手机版电脑qq登录入口,湖北省建设招投标监督机构网站Java基础#xff1a;面向对象#xff08;二#xff09; 文章目录 Java基础#xff1a;面向对象#xff08;二#xff09;1. 面向对象编程思想2. 类与对象2.1 类2.1.1 类的定义2.1.2 成员变量2.1.3 局部变量 2.2 对象2.2.1 对象的定义2.2.2 对象的使用2.2.3 对象创建的原理…Java基础面向对象二 文章目录 Java基础面向对象二1. 面向对象编程思想2. 类与对象2.1 类2.1.1 类的定义2.1.2 成员变量2.1.3 局部变量 2.2 对象2.2.1 对象的定义2.2.2 对象的使用2.2.3 对象创建的原理 3. 封装4. 构造方法5. 对象作为方法的参数或返回类型6. 对象数组6.1 声明数组变量6.2 创建数组对象 7. static关键字7.1 static可以修饰属性7.2 static可以修饰方法7.3 static可以修饰代码块7.4 单例模式7.4.1 饿汉式单例模式7.4.2 懒汉式单例模式 8. 使用访问修饰符实现封装8.1 包的概念8.2 导包操作8.3 静态导入 9. 代码封装10. this关键字11. 继承关系11.1 继承的概念11.2 继承类型11.3 继承的特性11.4 子类实例化过程11.5 属性的隐藏11.6 方法重写方法覆盖11.7 抽象方法和抽象类11.8 final关键字的用法 12. 多态12.1 多态的概念12.2 向上转型上溯造型12.3 向下转型下溯造型12.4 里式代换原则12.5 instanceof运算符 13. 组合关系14. 接口14.1 接口的概念14.2 语法格式14.3 接口的应用14.3.1 接口的多态14.3.2 接口与抽象类14.3.3 简单工厂模式14.3.4 工厂方法模式14.3.5 缺省适配器模式 15. 内部类15.1 简介15.2 分类15.2.1 成员内部类普通内部类15.2.2 静态内部类15.2.3 局部内部类15.2.4 匿名内部类 1. 面向对象编程思想 面向对象分析Object Oriented AnalysisOOA面向对象分析是软件开发过程的第一步它主要关注于对问题域的理解和分析。面向对象设计Object Oriented DesignOOD面向对象设计是在面向对象分析的基础上进行的它主要关注于如何将分析阶段得到的需求转化为具体的设计。面向对象编程Object-Oriented ProgrammingOOP面向对象编程是面向对象软件开发的实现阶段它主要关注于使用面向对象编程语言来实现设计阶段的成果。面向对象编程的主要特性包括封装性、继承性、多态性这些特性有助于提高代码的可重用性、可维护性和可扩展性。 2. 类与对象 2.1 类 2.1.1 类的定义 在Java中类Class是对象Object的模板它定义了一类对象的属性和行为。类的定义格式如下 [访问修饰符] class 类名{成员变量(属性);成员方法(行为);内部类;代码块; }2.1.2 成员变量 成员变量包括实例变量和静态变量是定义在类中方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。Java中类的成员变量都有默认值。例如整数类型为0浮点数类型为0.0布尔类型为false字符类型为\u0000引用类型为null。 2.1.3 局部变量 在方法体、方法参数或者代码块中定义的变量被称为局部变量。局部变量没有默认值声明和初始化都是在方法中方法结束后变量就会自动销毁。 ❓问成员变量有默认值局部变量没有默认值产生的原因? ✅答成员变量和局部变量在默认值行为上的差异主要源于它们在生命周期、存储位置、作用域和初始化机制上的不同。以下是具体的原因 生命周期 成员变量随着类的实例化或类的加载而被创建并在类的实例或类本身被销毁时销毁。 局部变量在方法、构造函数或初始化块执行时创建并在执行完毕后销毁。存储位置 成员变量实例变量存储在堆内存中随着对象的创建而分配静态变量存储在方法区也称为静态存储区或类变量区。 局部变量存储在栈内存中每个方法执行时都会在栈内存中创建一个栈帧局部变量就存储在这个栈帧中。作用域 成员变量可以在类的任何方法中访问对于实例变量或在类的外部通过类的实例或类名对于静态变量访问。 局部变量只能在声明它们的方法、构造函数或初始化块内部访问。初始化 成员变量如果没有显式地初始化Java在创建类的实例或JVMJava虚拟机类加载时会自动为成员变量赋予默认值。 局部变量使用前必须显式初始化否则编译时会出现错误。 2.2 对象 2.2.1 对象的定义 对象是类的一个实例有状态和行为。类和对象的关系就是抽象和具体的关系。创建对象的基本语法格式如下 类名 对象名 new 类名();2.2.2 对象的使用 调用对象的属性和方法如果是在当前类中可以直接访问属性和方法。如果在其他类中通过点.运算符来访问其属性和方法。例如如果有一个名为Person的类需要创建per1、per2、per3三个对象使用set和get方法对属性进行赋值和取值操作。代码示例如下 /* Test.java */ public class Test {public static void main(String[] args) {Person per1 new Person();Person per2 new Person();Person per3 new Person(王麻子, 28);per1.setName(张三);per1.setAge(10);per2.setName(李四);per2.setAge(18);per1.init();System.out.println(姓名 per2.getName());System.out.println(年龄 per2.getAge());per3.init();} } /* Person.java */ public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name name;this.age age;}public void init() {System.out.println(姓名 name);System.out.println(年龄 age);}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;} }运行结果 姓名张三 年龄10 姓名李四 年龄18 姓名王麻子 年龄282.2.3 对象创建的原理 在Java虚拟机JVM的内存模型中程序计数器、Java栈、堆、本地方法栈和方法区是五个重要的组成部分。当使用new关键字创建一个对象时同时操作了栈和堆在栈内存中保存对象的引用对象的首地址在堆内存中保存对象的属性。编写.java文件源文件的时候文件存储在硬盘上这个文件只是包含了类的定义和源代码但它并没有被JVM加载到内存中执行。当编译这个.java文件时Java编译器如javac命令会检查源代码的语法和语义。编译成功后它会生成一个或多个.class文件类文件。这些类文件包含了JVM执行程序所需的字节码Byte-code和其他信息。当运行如java命令包含main方法的类时JVM会加载这个类文件到内存中。加载过程中JVM会执行以下步骤 加载JVM通过类加载器ClassLoader查找并加载指定的类文件到内存中。链接 验证确保被加载的类的正确性和安全性。准备为类的静态变量分配内存并将其初始化为默认值。解析把类中的符号引用转换为直接引用。 初始化为类的静态变量赋予正确的初始值。 操作对象都是通过引用完成一旦引用出栈没有被引用的对象就变成了垃圾JVM的垃圾回收器Garbage CollectorGC会负责回收其占用的内存空间。 3. 封装 定义封装是将类的某些信息隐藏在类的内部不允许外部程序直接访问而是通过该类提供的方法来对隐藏的信息进行操作和访问。具体来说封装通过定义私有变量使用private作为访问修饰符和公有方法公共的getter和setter方法来实现私有变量只能在类的内部访问而公有方法可以在类的外部访问和调用。 作用数据隐藏提高代码的可维护性实现接口和抽象。降低耦合性实现高内聚、低耦合。 4. 构造方法 在Java中构造方法也称为构造函数或构造器是一种特殊的方法用于在创建对象时初始化该对象的状态。构造方法的基本语法格式如下 public class ClassName { // 类的成员变量 // ... // 构造函数 public ClassName() { // 构造函数的实现代码 // 这里可以初始化类的成员变量等 } // 如果有需要可以定义带参数的构造函数 public ClassName(parameterType1 parameter1, parameterType2 parameter2, ...) { // 构造函数的实现代码 // 这里可以使用传入的参数来初始化类的成员变量等 } // 类的其他方法 // ... }名称构造方法的名称必须与类名完全相同。这是Java语言规定的一个特性以便在创建对象时能够自动调用相应的构造方法。返回类型构造方法没有返回类型也不允许使用void关键字声明返回类型。这是因为构造方法的主要目的是初始化对象而不是返回任何值。访问修饰符构造方法可以使用访问修饰符如public、protected、private来限制其可见性和可访问性。通常构造方法被声明为public以便可以从类的外部创建对象。但是在某些情况下你可能希望将构造方法声明为protected或private以实现特定的设计目标如单例模式、工厂方法等。参数列表构造方法可以具有任意数量和类型的参数。这些参数在创建对象时通过new关键字传递给构造方法以便在初始化对象时使用。通过提供不同参数的构造方法可以实现对象的多样化初始化。默认构造方法在Java中每个类至少有一个构造方法。如果你没有显式地定义任何构造方法那么Java编译器会自动为你生成一个默认的无参构造方法。如果你定义了至少一个构造方法默认的无参构造方法可能不会被自动生成。构造方法的调用如果是在其他类中通过new的方式来调用构造方法如果是在自己的类中可以在构造方法之间进行互相调用。使用this([参数])必须写在构造方法中的第一行。继承子类不会继承父类的构造方法但子类构造方法可以通过super()关键字调用父类的构造方法。 5. 对象作为方法的参数或返回类型 创建一个类然后创建该类的对象并将这些对象作为参数传递给方法或作为方法的返回值。代码示例如下 public class Person { private String name; private int age; // 构造方法、getter和setter方法... // 示例方法接受Person对象作为参数 public void greet(Person otherPerson) { System.out.println(this.name says hello to otherPerson.getName()); } // 示例方法返回Person对象 public Person getOlderPerson(Person person) { if (this.age person.getAge()) { return this; } else { return person; } } }6. 对象数组 对象数组是一种可以存储多个对象的数组。每个数组元素都可以是一个对象的引用指向一个实际的对象。 6.1 声明数组变量 声明一个数组变量指定数组将要存储的对象的类型并使用方括号[]表示它是一个数组。 Student[] students; // 声明一个Student类型的数组变量6.2 创建数组对象 使用new关键字和类的名称来创建数组对象并指定数组的大小即它可以存储的元素数量。 students new Student[3]; // 创建一个可以存储3个Student对象的数组。或者可以在声明变量的同时创建数组对象 Student[] students new Student[3]; // 类名[] 数组 new 类名[数组长度];代码示例如下 // Test.java public class Test {public static void main(String[] args) {Student student1 new Student(小明, 男);Student student2 new Student(小红, 女);Student student3 new Student(小丽, 女);Teacher teacher new Teacher();Student[] students new Student[3];students[0] student1;students[1] student2;students[2] student3;teacher.sign(students);} } // Teacher.java public class Teacher {public void sign(Student[] students) {for (Student student : students) {String gender student.getGender();if (gender.equals(男)) {System.out.println(student.getName() 到);} else {System.out.println(student.getName() 有);}}} } // Student.java // ...运行结果 小明到 小红有 小丽有7. static关键字 7.1 static可以修饰属性 静态成员变量类成员变量使用static修饰的作用范围在整个类的所有对象上。所有对象共享这个变量在内存中只有一个副本。访问通过类名.变量名访问。在类加载时被初始化存储在堆里。实例成员变量没有static修饰作用范围在某个实例对象上。在创建对象时被初始化存在多个副本。各个对象不互相影响。通过实例对象名.变量名访问。 7.2 static可以修饰方法 静态方法类方法使用static修饰不能直接使用实例变量只能直接使用静态变量。只能直接调用静态方法不能直接调用实例方法。通过类名.方法名()访问。不允许使用this关键字代表对象。实例方法没有static修饰既可以使用静态变量又可以使用实例变量。既可以直接访问实例方法又可以直接访问静态方法。 通过实例对象名.方法名()访问。 代码示例如下 public class Car {// 静态成员变量public static int count 0;// 实例成员变量private String licenseNumber;private String brand;// 构造方法public Car(String licenseNumber, String brand) {this.licenseNumber licenseNumber;this.brand brand;// 每次创建Car对象时都更新静态变量countcount;}// 静态方法用于返回当前Car对象的数量public static int getCurrentNumberOfCars() {return count;}// 实例方法用于显示Car对象的详细信息public void displayDetails() {System.out.println(第 count 辆车的车牌号是 licenseNumber 品牌是 brand);}public static void main(String[] args) {// 可以通过类名直接访问静态成员变量System.out.println(最初车的数量 Car.count);// 创建Car对象通过对象引用访问实例成员变量、实例方法Car car1 new Car(A12345, 问界M9);System.out.println(第 count 辆车的车牌号是 car1.licenseNumber 品牌是 car1.brand);Car car2 new Car(B67890, 小米SU7);car2.displayDetails();// 可以通过类名访问静态方法获取Car对象的数量System.out.println(目前车的数量 Car.getCurrentNumberOfCars());} }运行结果 最初车的数量0 第1辆车的车牌号是A12345品牌是问界M9 第2辆车的车牌号是B67890品牌是小米SU7 目前车的数量27.3 static可以修饰代码块 执行顺序和优先级静态代码块构造代码块构造方法。 静态代码块类加载的时候执行并且只执行一次优先于各种代码块和构造方法最开始执行的。构造代码块在创建对象时被调用每创建一次对象都会执行一次构造代码块。 执行顺序优先于构造方法执行。一个类如果有多个构造方法时每通过构造方法创建一个对象代码块都会被执行一次。但是对于构造方法来讲只执行某一个构造方法根据参数执行。 代码示例如下 public class TestInitialization {public TestInitialization() {System.out.println(Constructor executed.);}{System.out.println(Instance block executed.);}static {System.out.println(Static block executed.);}public static void main(String[] args) {TestInitialization obj1 new TestInitialization();TestInitialization obj2 new TestInitialization();} }运行结果 Static block executed. Instance block executed. Constructor executed. Instance block executed. Constructor executed.7.4 单例模式 单例模式Singleton Pattern是一种创建型设计模式确保一个类只能创建一个实例对象自行实例化并向整个系统提供这个对象。 7.4.1 饿汉式单例模式 饿汉式单例模式Eager Initialization Singleton是一种在类加载时就立即创建单例实例的设计模式。这种模式相比于懒汉式单例模式Lazy Initialization Singleton它的优势在于其线程安全性因为JVM在加载类时会对静态变量进行初始化并且这个初始化过程是线程安全的。 // 饿汉式单例模式 public class Singleton {private Singleton() { // 私有构造函数防止外部通过new创建实例}private static final Singleton single new Singleton(); // 提供一个当前类的私有静态成员变量public static Singleton getInstance() { // 提供一个公有的静态方法返回成员变量return single;} }7.4.2 懒汉式单例模式 非线程安全的懒汉式单例模式是最基本的懒汉式单例模式实现但在多线程环境下是不安全的。 // 非线程安全的懒汉式单例模式 public class Singleton2 {private Singleton2() {}private static Singleton2 singleton;public static Singleton2 getInstance() {if (singleton null)singleton new Singleton2();return singleton;} }为了保证懒汉式单例模式的线程安全通常有以下3种方法 线程安全的懒汉式单例模式使用synchronized关键字来保证线程安全但这种方式在性能上较差因为每次调用getInstance()方法时都需要进行同步双重检查锁定Double-Check LockingDCL的懒汉式单例模式DCL模式通过两次检查实例是否为null来避免不必要的同步是线程安全且性能较好的实现方式。为了避免指令重排导致的问题需要将instance声明为volatile // 双重检查锁定的懒汉式单例模式 public class Singleton3 {private volatile static Singleton3 instance;private Singleton3() {}public static Singleton3 getInstance() {if (instance null) { // 第一次检查 synchronized (Singleton3.class) {if (instance null) { // 第二次检查 instance new Singleton3();}}}return instance;} }静态内部类的懒汉式单例模式利用静态内部类的特性来实现懒汉式单例模式这种方式既保证了线程安全又避免了同步带来的性能开销。 // 静态内部类的懒汉式单例模式 public class Singleton4 {private Singleton4() {}// 静态内部类 private static class Singleton4Holder {private static final Singleton4 INSTANCE new Singleton4();}// 提供全局访问点 public static Singleton4 getInstance() {return Singleton4Holder.INSTANCE;} }8. 使用访问修饰符实现封装 8.1 包的概念 包Package是Java中用于组织类的命名空间。它可以把相关的类、接口、枚举和注解组合在一起形成一个逻辑上的单元。包的主要目的是为了解决类的命名冲突和进行更好的代码组织。 以下是一些在Java类库中比较常用的包 包名说明java.langjava语言包不需要进行导包就可以使用的java.utiljava实用工具包java.iojava输入输出流包java.sql操作数据库相关的包java.netjava网络包java.text处理文本、日期、时间、数字、消息的类和接口java.swing图形用户界面 包的用途 避免命名冲突可以按功能将类进行组合可以保护类、数据和方法。 注 package打包语句必须在代码的第一条语句。前面只能有空白和注释使用package时会在磁盘上生成对应的目录每个源文件只能有一条打包语句。 8.2 导包操作 在同一个包中类之间互相访问可以不需导包操作如果类不在同一个包下面需要使用import进行导包操作。 import可以出现多次。声明在package之后在class之前。导包可以使用通配符*。 8.3 静态导入 静态导入Static Import是一种导入静态成员例如静态方法、静态字段或静态枚举常量的方式而无需通过类名来引用它们。要使用静态导入需要使用import static关键字。代码示例如下 import static com.coder.test.MathUtils.add;9. 代码封装 代码封装通常指的是使用不同的访问修饰符Access Modifiers来控制类、成员变量属性和方法的可见性和可访问性。Java提供了四种访问修饰符 privatedefaultprotectedpublic同类TTTT同包FTTT子类FFTT通用性FFFT 属性和方法的访问修饰符 public公有的最高的访问权限所有类都可以访问不管是否同包。protected受保护的可以被同包的类访问以及不同包中的子类访问。default无修饰符也称为包级私有或默认访问权限不使用访问修饰符关键字来声明表示默认当前类和同包可以访问。private只能在当前类中访问不对外公开。 类的访问修饰符 public所有类都可以访问。default只能当前包中访问。 10. this关键字 this.属性名用于引用当前对象的该属性。this.方法名()用于调用当前对象的该方法。this([参数])用于调用当前类的另一个构造器这称为构造器的重载调用或构造器链。必须是构造器构造方法中的第一个语句且只能调用一次。this用于返回当前对象的引用。 11. 继承关系 11.1 继承的概念 继承是一种机制它允许一个类称为子类、派生类或扩展类继承另一个类称为父类、超类或基类的属性和方法。子类可以继承父类的所有非私有成员即public、protected和default并且可以选择性地覆盖Override父类的方法或者添加新的属性和方法。继承关系通常被称为is-a关系。继承的语法格式如下 class 父类 { }class 子类 extends 父类 { }11.2 继承类型 Java主要支持的是单一继承Single Inheritance即一个类只能直接继承自一个父类。 11.3 继承的特性 Java继承具有以下几个主要特性 单一继承Java只支持单继承即一个类只能有一个直接的父类。虽然直接继承是单一的但可以通过多层继承来间接地继承多个类的特性。继承属性和方法子类可以继承父类的非私有public、protected属性和方法。子类可以访问和操作这些继承来的属性和方法。方法重写Override子类可以提供一个与父类方法签名相同方法名、参数列表和返回类型相同但实现不同的方法。当通过子类对象调用该方法时将执行子类中的方法实现而不是父类中的方法。构造方法不被继承子类不继承父类的构造方法。但子类可以通过调用父类的构造方法来初始化从父类继承的属性。这通常通过super()关键字在子类构造方法中完成。访问权限子类可以访问父类的公有public和保护protected成员但不能直接访问父类的私有private成员必须通过getter或setter方式进行访问。多态性继承是实现多态性的基础之一。多态性允许在运行时根据对象的实际类型来调用相应的方法。例如父类引用可以指向子类对象并调用子类重写的方法。super关键字子类可以通过super关键字来引用父类的属性和方法。这允许子类在需要时访问父类的实现或数据。初始化顺序在子类实例化时首先执行父类的静态代码块然后执行子类的静态代码块。接着当创建子类对象时会先调用父类的构造方法如果有通过super()显式调用或者隐式调用然后执行子类的构造方法中的代码。子类可以添加新的属性和方法子类可以拥有父类所没有的属性和方法这扩展了父类的功能。final类和final方法如果一个类被声明为final则它不能被继承。同样如果一个方法被声明为final则它不能在子类中被重写。 11.4 子类实例化过程 子类实例化过程加载类包括父类和子类——初始化静态变量和静态初始化块——分配内存——调用父类构造函数——初始化父类实例变量和实例初始化块——执行父类构造函数体——初始化子类实例变量和实例初始化块——执行子类构造函数体——对象创建完成。 ❓问在子类创建对象时是否也创建了父类的对象 ✅答不会创建父类对象只是创建了父类空间并进行了初始化操作。 注 如果父类有无参的构造方法子类super()可以省略如果父类中没有无参的构造方法子类super(参数)不可以省略如果使用super()显式地调用父类的构造方法要求必须写在子类构造方法中的第一行子类的构造方法中不能同时出现super()和this()。 11.5 属性的隐藏 在父类中定义一个属性在子类中定义了一个同名的属性在子类中访问会隐藏父类的属性。在子类中有两个同名属性一个是继承自父类的使用super属性名访问一个是子类自己的使用this属性名访问。在方法中如果访问到属性继承自父类的方法使用的是父类的属性子类自己的方法使用的是子类属性。 代码示例如下 public class TestPro {public static void main(String[] args) {Son son new Son();son.showName();son.testName();} } class Father {String name 父类的属性;public void testName() {System.out.println(3. name);} } class Son extends Father {String name 子类的属性;public void showName() {System.out.println(1. name);System.out.println(2. super.name \t this.name);} }运行结果 1. 子类的属性 2. 父类的属性 子类的属性 3. 父类的属性如果父类中有一个静态变量则被所有子类所共享其中一个子类修改了值其他子类访问也是修改后的值。如果子类自己写了一个同名的静态变量则子类中访问的是自己的变量不再是父类变量。 代码示例如下 public class TestPro2 {public static void main(String[] args) {Son son new Son();son.showName(); // 打印父类的静态变量Son2 son2 new Son2();son2.setName(); // 修改静态变量的值son.showName();} } class Father {static String name 父类的属性;public void testName() {System.out.println(3. name);} } class Son extends Father {// static String name 子类的属性;public void showName() {System.out.println(4. name);} } class Son2 extends Father {public void setName() {name 新子类的属性;} }运行结果 4. 父类的属性 4. 新子类的属性11.6 方法重写方法覆盖 方法重写Override是面向对象编程的一个重要概念它发生在子类与父类之间。方法重写的使用有以下要求 方法签名相同方法名、参数列表必须相同返回类型相同或子类返回类型必须相同或者是其子类访问权限不能更严格子类方法的访问权限public、protected、default、private不能低于父类中被重写的方法的访问权限不能重写final方法如果父类中的方法被声明为final那么它不能被重写不能重写static方法如果父类中的方法是static的那么子类中的同名同参数列表的方法并不是覆盖父类方法而是隐藏了父类方法因为static方法是与类关联的而不是与对象关联的所以它们不参与多态使用Override注解在Java中建议在使用重写时加上Override注解。这样如果子类的方法不符合重写的要求比如方法签名不匹配编译器会报错抛出异常不能更广泛子类方法抛出的异常类型必须是父类方法抛出的异常类型的子集或者相同子类方法不能抛出比父类方法更多的异常但可以选择不抛出异常。 注 使用方法重写的场景子类和父类的方法要完成相同功能但采用不同的算法或公式。必须要重写的方法抽象方法由abstract修饰必须在子类中被重写。不能重写的方法构造方法constructor、私有方法由private修饰、最终方法由final修饰、静态方法由static修饰。 11.7 抽象方法和抽象类 抽象Abstraction是实现设计和实现相分离的一种关键手段。这种分离是面向对象编程OOP的基本原则之一它使得软件设计更加模块化、可维护和可扩展。 抽象方法使用abstract关键字修饰只有方法的声明方法头没有方法的实现方法体。不能是静态方法。抽象类使用abstract关键字修饰可以有抽象方法也可以有普通方法也可以有构造方法也可以没有抽象方法。如果一个类中有抽象方法则这个类必须是抽象类。抽象类不能实例化。 11.8 final关键字的用法 final可以用来修饰类、方法、变量包括实例变量、静态变量和局部变量和常量表达式。以下是final关键字的用法 定义终结类最终类 当一个类定义为final时就表明不能继承这个类表示不能产生子类。final类里面的所有方法都是隐式的final不会产生子类也不会覆盖方法所以不需要在final类中为方法加final关键字。 定义终结方法 不能被子类重写。所有private方法都是隐式的final方法在private方法中不需要使用final关键字修饰。final方法可以被重载同名参数列表不同。 代码示例如下 private int test1() {return 0; } //... public final void test2() {//... } public final void test2(int x) {//... }定义常量 修饰引用类型无法更改引用所指向的对象地址但引用的对象属性可以修改。修饰基本数据类型无论是编译期常量还是非编译期常量一旦它们被初始化它们的值就不能再被修改。static finalstatic final的作用主要是用来声明全局常量这些常量属于类并且其值不能被改变。这样的常量通常在类加载时初始化并且可以在整个应用程序中通过类名来访问。 代码示例如下 public class Test {// 编译期常量final int[] a {10, 20, 30, 40}; // 引用类型final int i 10; // 基本数据类型// 非编译期常量Random random new Random();final int j random.nextInt(10);public static void main(String[] args) {final Student student new Student(); // 引用类型student.setName(张三);student.setGender(男);student.setName(李四);System.out.println(student);Test t new Test();System.out.println(t.i);System.out.println(t.j);} } class Student {//...Overridepublic String toString() {return Student{ name name \ , gender gender \ };} }运行结果 Student{name李四, gender男} 10 6注final不可以和abstract放在一起对方法和类进行修饰。 12. 多态 12.1 多态的概念 在Java中多态Polymorphism是面向对象编程的三大特性之一封装、继承和多态它允许我们以统一的方式处理不同类型的对象。以下是多态的必要条件和优点 多态的必要条件 继承关系多态需要存在继承关系。方法重写子类必须重写父类的方法以实现自己的特有行为。父类引用指向子类对象在程序中使用父类类型的引用变量指向子类对象即将子类对象赋给父类引用变量。父类引用调用重写方法通过父类引用变量调用子类对象中重写的方法。运行时绑定通过动态绑定机制根据对象的实际类型来调用相应的方法。这是实现多态的关键机制之一。 多态的优点 简化代码。面向抽象编程不面向具体编程依赖倒转原则。易于扩展增强代码可读性。 12.2 向上转型上溯造型 向上转型Upcasting是指将子类的引用赋值给父类类型的变量。由于子类继承了父类的所有属性和方法除了私有属性和方法因此父类类型的变量可以引用子类对象。这种转换是自动的不需要显式地进行类型转换。语法格式如下 父类类型 对象名 new 子类类型();12.3 向下转型下溯造型 向下转型Downcasting是指将父类类型的引用转换为子类类型的变量。由于父类引用可能指向的是子类对象也可能是其他子类对象或父类对象本身因此这种转换是不安全的因为它可能会导致ClassCastException。为了进行向下转型我们需要显式地使用类型转换操作符并且最好使用instanceof关键字进行检查以确保转换是安全的。语法格式如下 子类类型 对象名 (子类类型)父类引用;代码示例如下 class Animal {void eat() {System.out.println(所有的动物都要吃东西);} } class Dog extends Animal {Overridevoid eat() {System.out.println(小狗爱吃骨头);} } class Cat extends Animal {Overridevoid eat() {System.out.println(小猫爱吃鱼);} } public class Main {public static void main(String[] args) {// 向上转型Animal animal1 new Dog();animal1.eat();Animal animal2 new Cat();// 向下转型if (animal2 instanceof Animal) { // 使用instanceof关键字进行检查Cat cat (Cat) animal2;cat.eat();}} }运行结果 小狗爱吃骨头 小猫爱吃鱼12.4 里式代换原则 里式代换原则Liskov Substitution PrincipleLSP是面向对象设计的基本原则之一。这个原则强调了在程序设计中子类应当能够替换其父类并出现在父类能够出现的任何地方而不会改变程序的行为。里式代换原则要求 子类必须完全实现父类的方法父类出现的地方子类一定可以出现子类出现的地方父类不一定可以出现。 12.5 instanceof运算符 判断一个对象是否属于某个类或其父类返回boolean类型的值如果属于就返回true否则返回false。 object instanceof Class其中object是要测试的对象Class是要检查的类名。 13. 组合关系 组合Composition关系是一种表示“部分-整体”关系的设计概念它表示一个对象组合对象包含另一个对象被组合对象作为其实例变量字段、属性。这种关系也称为has-a关系它表示一个对象有另一个对象作为其一部分。代码示例如下 class Engine {// Engine类的属性和方法private String type;public Engine(String type) {this.type type;}public String getType() {return type;} } class Car {// Car类包含Engine类的实例变量表示组合关系private Engine engine;public Car(Engine engine) {this.engine engine;}public void start() {// 使用被组合对象的方法System.out.println(汽车开始启动 engine.getType() 引擎);} } public class Main {public static void main(String[] args) {Engine engine new Engine(V8);Car car new Car(engine);car.start();} }运行结果 汽车开始启动V8引擎注合成聚合复用原则Composite/Aggregate Reuse PrincipleCARP是面向对象设计中的一个重要原则它强调在复用代码时应该优先使用对象的组合/聚合关系而不是通过继承关系来达到复用的目的。 14. 接口 14.1 接口的概念 接口Interface是一个完全抽象的类它不能被实例化但可以被类实现Implement。实现关系通常被称为like-a关系。接口主要用于定义一组方法这些方法被称为接口方法这些方法不提供具体的实现而是由实现接口的类来提供。 14.2 语法格式 接口的语法格式如下 [修饰符] interface 接口名 [extends 接口名[, 接口名...]] { // 常量字段 [public] [static] [final] 数据类型 常量名 值; // 抽象方法 [public] [abstract] 返回类型 方法名(参数列表); // 默认方法从JDK 1.8开始 [public] default 返回类型 方法名(参数列表) { // 方法体 } // 静态方法从JDK 1.8开始 [public] static 返回类型 方法名(参数列表) { // 方法体 } // 私有方法从Java 9开始 // 私有静态方法 private static 返回类型 方法名(参数列表) { // 方法体 } // 私有实例方法从Java 9开始 private 返回类型 方法名(参数列表) { // 方法体 } }类的语法格式如下 [修饰符] class 类名 [implements 接口名[, 接口名...]] { // 成员变量字段 [修饰符] 数据类型 变量名; // 构造方法 [修饰符] 类名(参数列表) { // 构造方法体 } // 方法 [修饰符] 返回类型 方法名(参数列表) { // 方法体 } // 初始化块可选 { // 初始化代码 } // 内部类、接口等可选 }其中 接口的定义[访问修饰符] interface 接口名{}。接口中的数据成员变量默认都是public static final的也就是公有的静态常量。接口中的方法默认是public abstract的因此可以省略这些修饰符。从Java 8JDK 1.8开始接口中可以包含带有具体实现的方法称为默认方法使用default来标记。从Java 8开始接口中可以包含静态方法使用static来标记并且不能是抽象的。从Java 9开始接口中可以包含私有方法包括私有静态方法和私有实例方法这些私有方法只能在接口内部使用并且不能被实现类访问。接口不是类没有构造方法不能实例化。接口可以实现多继承。一个接口可以被多个类实现。类和接口的关系class 类名 implements 接口名{}。一个类可以实现多个接口class 类名 implements 接口1[,接口2...]{}。一个类可以在继承一个父类的同时实现一个或多个接口class 类名 extends 父类 implements 接口1[,接口2...]{}。 14.3 接口的应用 14.3.1 接口的多态 接口Interface是实现多态性Polymorphism的一种重要方式。接口的多态实现方式主要依赖于这三个关键概念接口定义类实现接口接口引用指向实现类的对象。代码示例如下 /* 接口定义 */ interface Shape { // 图形void draw();void calculateArea(); } /* 类实现接口 */ class Circle implements Shape { // 圆Overridepublic void draw() {System.out.println(画个圆);}Overridepublic void calculateArea() {// 实现计算圆面积的代码} } class Rectangle implements Shape { // 矩形Overridepublic void draw() {System.out.println(画个矩形);}Overridepublic void calculateArea() {// 实现计算矩形面积的代码} } public class Main {public static void main(String[] args) {/* 接口引用指向实现类的对象 */Shape shape1 new Circle(); // Circle 是 Shape 的一个实现Shape shape2 new Rectangle(); // Rectangle 也是 Shape 的一个实现// 调用 draw 方法shape1.draw();shape2.draw();// 调用接口中定义的其他方法shape1.calculateArea();shape2.calculateArea();} }运行结果 画个圆 画个矩形14.3.2 接口与抽象类 接口Interface和抽象类Abstract Class是两种用于实现多态性和代码重用的重要机制。接口与抽象类的主要区别 目的接口主要用于定义对象的行为规范而抽象类则用于定义对象的共同属性和行为的模板。方法接口只包含抽象方法而抽象类可以包含抽象方法和非抽象方法。继承与实现类通过extends关键字继承抽象类通过implements关键字实现接口。多重继承一个类可以实现多个接口但只能继承一个抽象类直接继承。字段接口中的字段都是常量隐式static和final而抽象类可以包含各种类型的字段。 14.3.3 简单工厂模式 简单工厂模式Simple Factory Pattern是属于创建型模式又叫做静态工厂方法Static Factory Method模式它由一个工厂类根据传入的参数来决定创建哪一种产品类的实例。简单工厂模式是最简单的工厂模式但它不是一种设计模式因为它没有遵循开闭原则Open-Closed Principle即扩展开放修改关闭。 代码示例如下 // 定义一个产品接口 interface Product {void use(); } // 实现产品接口的具体产品类 class ProductA implements Product {Overridepublic void use() {System.out.println(使用产品A);} } class ProductB implements Product {Overridepublic void use() {System.out.println(使用产品B);} } // 工厂类负责创建产品对象 class SimpleFactory {// 静态方法根据传入的参数创建对应的产品对象public static Product createProduct(String type) {if (A.equals(type)) {return new ProductA();} else if (B.equals(type)) {return new ProductB();} else {return null; // 或者抛出异常}} } // 客户端代码 public class Client {public static void main(String[] args) {// 使用工厂类创建产品对象Product productA SimpleFactory.createProduct(A);if (productA ! null) {productA.use(); }Product productB SimpleFactory.createProduct(B);if (productB ! null) {productB.use();}// 试图创建一个不存在的产品类型Product productC SimpleFactory.createProduct(C);if (productC null) {System.out.println(无法创建产品C);}} }运行结果 使用产品A 使用产品B 无法创建产品C14.3.4 工厂方法模式 工厂方法模式Factory Method Pattern定义一个用于创建对象的接口让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。在工厂方法模式中核心的工厂类不再负责所有产品的创建而是将具体创建的任务交给它的子类来完成。这样做既保证了核心类的稳定又使得子类可以根据自身需要来灵活创建对象。 代码示例如下 // 产品接口 interface Product {void use(); } // 具体产品类A class ProductA implements Product {Overridepublic void use() {System.out.println(使用产品A);} } // 具体产品类B class ProductB implements Product {Overridepublic void use() {System.out.println(使用产品B);} } // 工厂接口 interface Factory {Product createProduct(); } // 具体工厂类A class FactoryA implements Factory {Overridepublic Product createProduct() {return new ProductA();} } // 具体工厂类B class FactoryB implements Factory {Overridepublic Product createProduct() {return new ProductB();} } // 客户端代码 public class Client {public static void main(String[] args) {Factory factoryA new FactoryA();Product productA factoryA.createProduct();productA.use();Factory factoryB new FactoryB();Product productB factoryB.createProduct();productB.use();} }运行结果 使用产品A 使用产品B14.3.5 缺省适配器模式 缺省适配器模式Default Adapter Pattern是适配器模式Adapter Pattern的一个特殊形式是一种结构型设计模式用于处理接口中方法数量过多或者大部分方法都有默认实现的情况。缺省适配器模式通过提供一个实现了目标接口的缺省适配器类该类为接口中的每个方法都提供了默认实现从而允许子类继承该适配器类时只需要关注自己感兴趣的方法而不需要实现接口中的所有方法。 代码示例如下 // 目标接口 interface MyInterface {void method1();void method2();void method3();// ... 可能还有其他方法 } // 缺省适配器类实现了MyInterface接口并提供默认实现 class DefaultAdapter implements MyInterface {Overridepublic void method1() {System.out.println(Default implementation of method1);}Overridepublic void method2() {System.out.println(Default implementation of method2);}Overridepublic void method3() {System.out.println(Default implementation of method3);}// ... 其他方法的默认实现 } // 具体实现类继承自缺省适配器并覆盖部分方法 class MySpecificImplementation extends DefaultAdapter {Overridepublic void method1() {// 覆盖默认实现System.out.println(Specific implementation of method1);}// method2 和 method3 使用默认实现 } // 客户端代码 public class Main {public static void main(String[] args) {MyInterface myImpl new MySpecificImplementation();myImpl.method1();myImpl.method2();myImpl.method3();} }运行结果 Specific implementation of method1 Default implementation of method2 Default implementation of method315. 内部类 15.1 简介 在一个类中定义另一个类称作内部类Inner Class。内部类可以访问外部类中的属性和方法不需要创建外部类的对象。外部类要访问内部类的属性民和方法需要创建内部类的对象.如果内部类有和外部类同名变量和方法则内部类的变量和方法优先级更高。外部类修饰符public、default。内部类修饰符public、protected、default、private。 15.2 分类 15.2.1 成员内部类普通内部类 成员内部类Member Inner Classes可以直接访问外部类的变量和方法(包括私有和静态修饰的)不能使用static声明变量和方法的。编译后生成的class文件命名为 “外部类名$内部类名”。不能直接new一个内部类对象必须使用外部类对象来创建内部类对象。 代码示例如下 class Test {public static void main(String[] args) {OuterClass outer new OuterClass();OuterClass.MemberInner MemberInner outer.new MemberInner();MemberInner.test();} } class OuterClass {private int x 10;private static int y 20;class MemberInner {int x 30;public void test() {System.out.println(OuterClass.this.x x y);}} }运行结果 60注如果外部类和内部类具有相同名称的成员变量或方法内部类可以直接访问内部类的成员变量和方法如果内部类访问外部类的成员变量或方法时需要this关键字。 15.2.2 静态内部类 静态内部类Static Inner Classes使用static修饰的内部类不能直接访问外部类的非静态成员变量和方法。如果要访问外部类的实例变量和方法需要创建外部类的实例对象。可以创建静态变量和方法。静态内部类创建对象时不需要创建外部类的对象直接可以创建内部类的对象。代码示例如下 代码示例如下 class Test1 {public static void main(String[] args) {OuterStatic.test1(); // 类名.方法名()OuterStatic.InnerStatic innerStatic new OuterStatic.InnerStatic(); // 创建内部类的对象innerStatic.test(); // 实例对象名.方法名()OuterStatic.InnerStatic.test1();} } class OuterStatic {private int x 10;public static void test1() { // 静态方法System.out.println(OuterStatic);}static class InnerStatic {private static int y 20; // 静态变量public static void test1() { // 静态方法System.out.println(InnerStatic);}public void test() { // 实例方法test1();OuterStatic outer new OuterStatic();System.out.println(outer.x);}} }运行结果 OuterStatic InnerStatic 10 InnerStatic15.2.3 局部内部类 局部内部类Local Inner Classes定义在外部类的方法或代码块中。可以直接访问外部类的所有成员变量和方法包括私有的、静态的不能使用访问修饰符地位相当于局部变量可以使用final修饰防止其他类去继承。作用范围就在当前的方法或代码块中。 代码示例如下 class Test2 {public static void main(String[] args) {OuterLocal outerLocal new OuterLocal();outerLocal.outerMethod();} } class OuterLocal {public void outerMethod() {final int localVar 10; // 保证数据运行的一致性使用final来修饰class InnerLocal {public void display() {System.out.println(Accessing localVar: localVar);}}InnerLocal inner new InnerLocal();inner.display();} }运行结果 Accessing localVar: 1015.2.4 匿名内部类 匿名内部类Anonymous Inner Classes是没有类名的内部类通常用于继承一个类或实现一个接口并且只需要使用一次。常用于GUI编程中的事件监听器、线程等。匿名内部类不能定义构造函数。语法格式如下 new 类或接口 类的主体代码示例如下 例1 class Test3 {public static void main(String[] args) {AddInterface inter new AddInterface() {Overridepublic void add(int x, int y) {System.out.println(x y);}};OuterAnony anony new OuterAnony();anony.testAdd(inter, 10, 20);} } class OuterAnony {public void testAdd(AddInterface addInterface, int x, int y) {addInterface.add(x, y);} } interface AddInterface {void add(int x, int y); }例2 class Test3 {public static void main(String[] args) {OuterAnony anony new OuterAnony();anony.testAdd(new AddInterface() {Overridepublic void add(int x, int y) {System.out.println(x y);}}, 10, 20);} }例3 class Test3 {public static void main(String[] args) {OuterAnony anony new OuterAnony();anony.testAdd((x, y) - System.out.println(x y), 10, 20); // Lambda表达式} }运行结果 30✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 以上内容是关于Java面向对象的基础知识希望对初学者或再次学习者有所帮助基础打扎实不怕风吹雨打如果以上内容有错误或者内容不全望大家提出我也会继续写好每一篇博文 待续未完 欢迎观看和提问 下一篇Java基础异常三
http://www.hkea.cn/news/14561197/

相关文章:

  • 电商网站开发工具网站开发的实验心德
  • 国内免费注册二级域名的网站微信公众平台开发者工具
  • 做私活一个网站大概多少钱个人做论坛网站需要哪些备案
  • 店铺营业执照在哪个网站做年审深圳有好软件有限公司
  • 大同百度做网站多少钱开发个微网站多少钱
  • 关于网站设计的书永久免费wifi
  • 域名网站账号如何做二手车网站
  • 钢材销售都在哪个网站做做网站的公司
  • 网站模板d一品资源网做准考证的网站
  • 主流的网站开发技术有北辰苏州网站建设
  • 企业网站设计建设长春外国购物网站大全
  • 成都 专业 网站建设江苏省建筑信息平台
  • 双语版网站小程序注册开发流程
  • 网站怎么添加滤镜功能吗面向网站开发的相关知识
  • 网站名称与备案名称不一致前程无忧深圳招聘网站
  • 用手机建立自己的网站网站建设应该怎么做
  • 网站上线稳定后的工作怎样做一个好的网页
  • 做公司网站找谁怎么在百度推广自己的公司
  • 网站机房建设流程建设局网站安徽
  • 青岛建站合作用织梦搭建网站
  • 震旦集团网站建设合肥简川科技网站建设公司 概况
  • 做seo的网站是怎么样的北京网站怎么建设
  • 四川二级站seo整站优化排名wordpress 音乐播放器插件
  • 网站制作常见问题 图片版权营销型网站 案例
  • 南京品牌网站设计创建一个网站流程图
  • 网站建设公司怎么做的网站开发工具是啥
  • 永康门业微网站建设模拟建设网站
  • 做网站找顺的html手机版网站
  • wordpress公司展示网站模板广州宣传片拍摄制作的公司
  • 定制网站的好处什么叫门户类网站