还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
对象和类探索面向对象Java编程的基石面向对象编程是语言的核心理念,它通过对象和类的概念,为复杂Java系统建模提供了强大的工具本课程将带领大家深入探索面向对象Java编程的基础知识,理解对象与类之间的关系,以及如何利用这些概念创建高效、可维护的程序课程提纲与目标掌握面向对象基础概念Java理解类与对象的关系,学习如何定义类、创建对象以及管理对象生命周期学习类的构成要素深入了解属性、方法、构造函数等类的基本组成部分及其作用理解面向对象三大特性掌握封装、继承、多态的概念及实际应用场景实践案例分析通过实际编程练习巩固理论知识,体验面向对象编程的优势什么是面向对象编程()OOP现实世界映射面向对象编程是一种编程范式,它将现实世界中的实体和概念映射为程序中的对象,通过这些对象之间的交互来构建系统这种方法更符合人类思考问题的方式,使程序设计更加直观封装将数据(属性)和行为(方法)封装在一个单元(对象)中,对外隐藏实现细节,只暴露必要的接口这提高了代码的安全性和可维护性继承允许一个类(子类)继承另一个类(父类)的特性,促进代码重用,建立类之间的层次关系,反映现实世界中的是一种关系多态同一操作作用于不同的对象,可以有不同的解释和实现这增强了代码的灵活性和扩展性,是高质量软件设计的关键面向对象编程通过这三大核心特性,为软件开发提供了一种模块化、可重用且易于维护的方法它已成为现代软件工程的主流范式,被广泛应用于各类应用程序开发中与的关系Java OOP的面向对象本质JavaJava是一种纯面向对象的编程语言,它从设计之初就以面向对象编程为核心理念在Java中,除了基本数据类型外,几乎所有内容都是对象即使是基本类型,Java也提供了对应的包装类,使它们能够在需要对象的场合使用这体现了Java万物皆对象的设计哲学对象的本质状态(属性)反映对象的特征和数据行为(方法)定义对象可执行的操作标识(唯一性)区分不同对象的特性在程序中,对象是类的实例,是程序运行时在内存中创建的实体每个对象都占用一定的内存空间,用于存储其状态(属性Java值)对象通过其方法与其他对象交互,改变自身或其他对象的状态对象的这种状态与行为的结合,使它能够模拟现实世界中的实体例如,一个学生对象可能有姓名、学号等状态,以及学习、考试等行为这种抽象使程序设计更接近人类理解问题的方式对象举例与生活类比汽车对象手机对象银行账户对象属性颜色、品牌、速属性型号、屏幕尺寸、属性账号、余额、开度、油量电量户日期方法加速、刹车、方法打电话、发短方法存款、取款、加油信、充电查询余额对象与类的关系,可以类比为蓝图与实际建筑的关系类就像一张建筑蓝图,定义了建筑的结构和特征;而对象则是根据这张蓝图建造的实际房屋,每栋房屋都有其独特的特征(墙的颜色、家具摆设等),但基本结构遵循蓝图的设计这种类比帮助我们理解,同一个类可以创建多个对象,每个对象虽然结构相同,但状态(属性值)可以各不相同,就像根据同一张蓝图可以建造多栋外观相似但内部装饰不同的房屋类是什么?类的定义类是面向对象编程的基本单元,它是对象的蓝图或模板类定义了某一类对象的共同特征(属性)和行为(方法),描述了创建对象的过程和对象的特性类不占用内存空间(类定义本身),只有当创建类的实例(对象)时,才会分配内存类是抽象的概念,而对象是具体的实体类的组成部分通常包括类名、属性(成员变量)、方法(包括构造方法和普通方法)在Java中,类还可以包含静态块、内部类等高级结构类可以看作是定义对象的模具就像制作饼干需要饼干模具一样,创建对象需要先定义类模具决定了饼干的形状和基本特征,而实际制作出的每个饼干可能在装饰、口味上有所不同,这就像通过同一个类创建的不同对象可以有不同的属性值类与对象的关系类Class抽象的模板定义结构和行为编译时确定不占用数据空间实例化Instantiation创建过程分配内存初始化状态对象Object具体的实例拥有实际状态运行时存在占用堆内存空间类与对象的关系可以理解为类型与实例的关系类是抽象的概念模型,定义了一组对象共有的结构和行为,而对象是这种模型的具体实例一个类可以创建多个对象,就像同一个模具可以制作多个产品在Java中,类通过编译形成字节码文件.class,这些字节码包含了创建和操作对象所需的指令当程序运行并使用new关键字时,JVM会根据这些指令在内存中创建对象,分配空间,并初始化对象的状态类是静态的定义,而对象是动态的实体中类的定义基础Java声明类使用class关键字,后跟类名(按照命名规范,类名应以大写字母开头)类的内容被包含在花括号{}中例如public classStudent{}定义属性在类中声明变量,用于存储对象的状态属性通常声明为私有private,以实现封装例如private String name;private int age;实现方法在类中定义方法,描述对象能执行的操作方法包括构造方法(与类同名,用于创建对象)和普通方法(定义对象行为)例如public voidstudy{...}Java类的基本结构包括访问修饰符、类名、继承和实现声明、类主体典型的Java类定义如下public classClassName extendsParentClass implementsInterface1,Interface2{//成员变量(属性)//构造方法//其他方法}类语法示例Javapublic classCar{//成员变量(属性)private Stringbrand;private String model;private int year;private doublespeed;//构造方法public CarStringbrand,Stringmodel,intyear{this.brand=brand;this.model=model;this.year=year;this.speed=
0.0;}//行为方法public voidacceleratedouble amount{speed+=amount;System.out.println加速到:+speed+km/h;}public voidbrake{speed=0;System.out.println车辆已停止;}//getter和setter方法public StringgetBrand{return brand;}//其他getter和setter方法...}上面的代码展示了一个标准的Java类定义Car类包含了描述汽车特征的属性(品牌、型号、年份、速度)和描述汽车行为的方法(加速、刹车)构造方法用于创建Car对象并初始化其属性,而getter方法则提供了访问私有属性的途径属性(字段)在类中的作用成员变量类型访问权限数据类型•实例变量属于对象,每个实例独立•private仅类内部可访问•基本类型int,double,boolean等•静态变量属于类,所有实例共享•protected类、包、子类可访问•引用类型String,数组,自定义类等•常量使用final修饰,值不可变•public任何类都可访问•默认无修饰符包内可访问属性是类的重要组成部分,用于存储对象的状态信息良好的类设计通常将属性声明为私有private,通过公共的getter和setter方法提供受控访问,这种做法体现了封装性原则属性的命名应当符合Java命名规范,通常采用驼峰命名法,如firstName初始值可以在声明时设置,也可以在构造方法中赋值属性的类型和访问修饰符决定了数据的存储方式和访问范围,是设计类时需要仔细考虑的要素方法(行为)在类中的作用方法定义了对象可以执行的操作,是对象行为的具体实现在类中,方法由修饰符、返回类型、方法名、参数列表、异常声明和Java方法体组成根据功能和用途,方法可分为构造方法、访问器方法、修改器方法、业务方法和工具方法等getter setter方法的命名应当反映其功能,动词开头,采用驼峰命名法如方法签名由方法名和参数列表共同决定,支持方法calculateTotal Java重载,即同一个类中可以有多个同名但参数列表不同的方法方法是实现类行为和与外部交互的主要途径,也是封装实现细节的重要手段构造方法简析特点与类同名,无返回类型,可重载功能初始化对象状态,设置属性初值调用时机创建对象时通过关键字调用new构造方法是创建对象时自动调用的特殊方法,用于初始化新对象的状态如果类中没有显式定义构造方法,会提供一个默认无参构造方Java法一旦定义了带参数的构造方法,默认构造方法就不再自动提供,需要手动添加构造方法可以重载,允许以不同方式初始化对象常见的构造方法模式包括默认构造方法(无参)、全参构造方法(初始化所有属性)和部分参数构造方法(初始化部分关键属性)通过合理设计构造方法,可以提供创建对象的便捷途径,确保对象在创建时就处于有效状态对象的创建与内存分配声明引用变量在栈内存中创建一个引用变量例如Student student;使用关键字new在堆内存中分配空间调用构造方法初始化对象例如new Student引用赋值将对象的内存地址赋给引用变量例如student=new Student使用对象通过引用访问对象的属性和方法例如student.getName在Java中,对象创建是一个多步骤过程首先,使用new关键字在堆内存中分配空间;然后,调用构造方法初始化对象;最后,返回指向新创建对象的引用这个引用可以赋值给一个变量,通过这个变量访问和操作对象对象在堆内存中创建,而引用变量存储在栈内存中一个对象可以有多个引用指向它,当没有引用指向对象时,该对象成为垃圾回收的候选对象了解对象的内存模型对于编写高效的Java程序至关重要,尤其是在处理大量对象时对象声明与赋值流程1声明阶段创建引用变量,未指向任何对象例如Car myCar;2实例化阶段使用new关键字创建对象,调用构造方法例如new Car丰田,卡罗拉,2023;3赋值阶段将对象引用赋给变量例如myCar=new Car丰田,卡罗拉,2023;4使用阶段通过引用访问对象的属性和方法例如myCar.accelerate20;对象的声明与赋值过程可以合并为一条语句Car myCar=new Car丰田,卡罗拉,2023;,这是Java中最常见的对象创建方式在这条语句执行后,内存中发生了两个关键变化堆内存中创建了Car对象,栈内存中的myCar变量存储了该对象的引用理解这个过程对于掌握Java的引用类型至关重要需要注意的是,引用变量本身不是对象,它只是指向对象的指针当我们进行对象赋值操作(如Car anotherCar=myCar;)时,实际上是创建了另一个指向同一对象的引用,而非复制对象本身多个对象与独立性对象的独立性//创建两个汽车对象在面向对象编程中,通过同一个类创建的多个对象是相互独立的实Car sportsCar=new Car法拉利,F8,2023;体每个对象都有自己的属性值状态,一个对象的状态变化不会直Car familyCar=new Car本田,思域,2022;接影响其他对象//独立操作不影响彼此这种独立性使得程序能够模拟现实世界中多个同类实体并行存在的情sportsCar.accelerate100;//法拉利速度为100况,如多辆汽车、多个学生账户等familyCar.accelerate60;//思域速度为60//两个对象状态各自独立System.out.printlnsportsCar.getSpeed;//输出100System.out.printlnfamilyCar.getSpeed;//输出60对象的独立性是面向对象编程的核心特性之一尽管多个对象是基于同一个类创建的,具有相同的结构属性和方法,但每个对象在内存中都有独立的空间存储自己的状态这使得我们可以创建同一类的多个实例,每个实例具有不同的行为和数据类的访问修饰符默认无修饰符包级访问权限protected同包内的类以及子类可访问仅同包内的类可访问适用于需要在继承层次中共享的成员适用于封装实现细节但允许包内协作public private最宽松的访问级别最严格的访问级别任何其他类都可以访问仅类内部可访问适用于API接口和公共工具类适用于隐藏内部实现细节访问修饰符控制类及其成员(属性和方法)的可见性和可访问性对于顶级类(非内部类),只能使用public或默认(无修饰符)一个源文件中只能有一个public类,且文件名必须与该类名相同合理使用访问修饰符是实现良好封装的关键通常建议将类的属性设为private,通过public方法提供受控访问,这样可以保护数据的完整性,同时提供修改实现细节的灵活性,而不影响使用该类的代码成员变量和局部变量区别特性成员变量局部变量声明位置类中,方法外方法内,或方法参数生命周期随对象创建而产生,随对象销方法执行时创建,方法结束时毁而消失销毁内存位置堆内存(实例变量)或方法区栈内存(静态变量)默认值有默认值(如int为0,引用为无默认值,必须初始化后使用null)访问修饰符可以使用public,private,不能使用访问修饰符protected等静态修饰可以使用static关键字(类变量)不能使用static关键字成员变量和局部变量在Java中具有明显的区别成员变量代表对象的状态,存储在堆内存中,具有较长的生命周期;而局部变量用于方法内部的临时计算,存储在栈内存中,方法执行完毕即被回收了解这些区别对于正确设计类和方法至关重要例如,频繁创建和销毁的临时数据应声明为局部变量以提高内存效率;而需要在对象整个生命周期内保持的状态则应定义为成员变量命名时也应有所区分,避免成员变量和局部变量同名导致的混淆封装性基础数据隐藏受控访问实现细节保护将属性声明为,通过公共的和隐藏内部实现,只暴露private getter setter防止外部直接访问方法访问属性必要的接口保护数据的完整性,避可以在方法中添加验证允许修改实现而不影响免非法修改逻辑,确保数据有效外部使用封装是面向对象编程的核心原则之一,它通过限制对对象内部数据的直接访问,提供了数据保护和代码灵活性在中,封装通常通过将属性声明为私有Java,并提供公共的访问器方法和修改器方法来实现private publicgettersetter标准的模式就是封装的典型应用,它规定了属性私有化、提供JavaBean方法的编码规范这种模式不仅保护了数据,还提供了修改实现的灵getter/setter活性例如,可以在方法中添加数据验证逻辑,或者在方法中按需计setter getter算派生属性,而不破坏类的使用方式封装带来的编程优势信息隐藏提高代码可维护性封装隐藏了对象的实现细节,使用者只需知通过封装,类的内部实现可以在不影响外部道如何使用对象的公共接口,而不需要了解代码的情况下进行修改例如,可以更改属内部工作原理这种信息隐藏降低了系统的性的存储方式、添加缓存机制或日志记录,复杂性,使开发者可以专注于更高层次的功而类的使用者无需修改他们的代码这大大能实现提高了代码的可维护性和可扩展性数据保护封装通过限制对属性的直接访问,保护了数据的完整性通过setter方法可以添加数据验证逻辑,确保对象始终处于有效状态这种保护机制降低了程序错误的可能性,提高了系统的健壮性封装是实现面向接口编程的基础通过定义清晰的公共接口,封装使得代码模块之间的耦合度降低,提高了代码的可重用性类的使用者只需关注做什么(接口),而不需要知道怎么做(实现),这符合现代软件工程的设计原则在实际开发中,良好的封装设计可以显著提高团队协作效率,不同的开发者可以在约定的接口下独立工作,减少相互干扰封装也是实现其他面向对象原则(如单一责任原则、开闭原则)的重要手段类的继承机制类Object所有类的根父类父类超类/提供基本属性和方法子类继承父类特性并可扩展继承是面向对象编程的三大特性之一,通过关键字实现子类自动获得父类的属性和方法(除了私有成员),可以在此基础上添加Java extends新的属性和方法,或者重写父类的方法只支持单继承,即一个类只能有一个直接父类,但可以通过多层继承形成继承链Java继承建立了类之间的是一种关系,例如狗是一种动物这种关系使得程序能够以层次化的方式组织代码,促进代码重用,减少冗余is-a在设计类继承关系时,应遵循里氏替换原则子类对象必须能够替换父类对象,而程序行为不发生变化继承的实际应用(动物基类)Animal•name动物名称•age年龄•eat进食方法•sleep睡眠方法(猫类)Cat•继承Animal的所有非私有成员•climbTree攀爬树木方法•meow猫叫方法•重写eat猫特有的进食行为(狗类)Dog•继承Animal的所有非私有成员•fetchBall捡球方法•bark狗叫方法•重写eat狗特有的进食行为在实际编程中,继承能够显著减少代码重复,提高开发效率通过将共同特征提取到父类中,各个子类只需关注自己特有的功能例如,在图形用户界面GUI开发中,可以创建一个基本的Component类,然后派生出Button、TextField等子类,它们共享组件的基本特性,同时各自实现特定的行为继承也是框架设计的重要工具许多Java框架(如Spring、Hibernate)大量使用继承,允许开发者通过扩展预定义的基类来自定义行为在设计自己的类层次时,应遵循组合优于继承的原则,只在确实存在是一种关系时使用继承,以避免过度耦合和过于复杂的继承层次方法重写()Override方法重写的规则public classAnimal{public voidmakeSound{•方法名、参数列表必须与父类方法相同System.out.println动物发出声音;•返回类型必须相同或是父类返回类型的子类型}•访问权限不能小于父类方法}•不能抛出更广泛的检查异常public classDog extends Animal{重写与重载的区别重写是子类对父类方法的重新实现,方法签名相同;重载是同一个类中多个同名但@Override参数不同的方法public voidmakeSound{System.out.println狗汪汪!;}}public classCat extendsAnimal{@Overridepublic voidmakeSound{System.out.println猫喵喵!;}}方法重写是实现多态的重要机制,它允许子类根据自身特性提供父类方法的特定实现当使用父类引用指向子类对象时,调用方法会执行子类的重写版本,而非父类版本这种运行时的行为是Java多态性的核心特征使用@Override注解是良好的编程实践,虽然它是可选的,但有两个重要优势首先,它向编译器明确表示这是重写方法,如果方法签名与父类不匹配,编译器会报错;其次,它提高了代码的可读性,明确表示该方法重写了父类方法方法重写为继承体系提供了灵活性,使不同子类能够以不同方式响应相同的方法调用关键字简介super访问父类成员调用父类构造方法使用super.属性名访问父类属性,使在子类构造方法中使用super参数列用super.方法名调用父类方法当表调用父类构造方法必须是构造子类方法重写了父类方法,但仍需方法的第一条语句如果子类构造使用父类实现时,这种用法特别有方法没有显式调用super,编译器用会自动插入super调用无参构造区分同名成员当子类和父类拥有同名属性或方法时,使用super关键字明确引用父类成员,使用this关键字引用子类成员,避免歧义和混淆super关键字是Java继承机制中的重要工具,它提供了子类访问父类成员的途径在构造方法链中,super调用确保了对象创建时父类部分得到正确初始化这是Java对象构造的重要机制,遵循从基类到派生类的初始化顺序在方法重写场景中,super.方法名允许子类扩展父类行为而不是完全替换它例如,子类可以首先调用父类的实现,然后添加自己的额外操作这种做法在框架开发中很常见,为继承链上的每个类提供了添加自己行为的机会,同时保留了基本功能多态性的概念实例代码实现机制Animal animal1=new Dog;//父类引用指向子类对象定义Java的多态性基于向上转型父类引用可以指向子类Animal animal2=new Cat;//父类引用指向另一子类对多态性是面向对象的核心特性,允许不同的对象对同一对象当通过这个引用调用重写的方法时,实际执行的象消息(方法调用)做出不同的响应在Java中,多态主是子类中的实现,而非父类中的实现animal
1.makeSound;//输出汪汪!要通过方法重写和接口实现来体现animal
2.makeSound;//输出喵喵!多态性增强了代码的灵活性和可扩展性通过使用父类类型或接口类型的引用,我们可以编写通用代码,处理不同类型的对象这种设计使得添加新的类变得简单只需创建一个新的子类,实现必要的方法,而无需修改已有代码Java的多态是动态多态(运行时多态),由JVM在运行时根据对象的实际类型决定调用哪个方法这与方法重载(静态多态或编译时多态)不同,后者在编译时就已确定多态是针对接口编程,而非实现设计原则的基础,是实现松耦合、高内聚系统的关键技术多态带来的代码优雅代码解耦提高扩展性多态允许代码操作抽象类型,而不是具体实现,降低添加新功能只需创建新的子类,而不需要修改现有代了组件之间的依赖性例如,使用List接口而不是具体码这符合开闭原则对扩展开放,对修改关闭的ArrayList类,使得代码可以适应不同的列表实现//已有Dog,Cat类,添加Bird只需class BirdextendsAnimal{...}ListString list=new ArrayList;//可轻松替换为LinkedList简化设计模式多态是许多设计模式的基础,如工厂模式、策略模式等它允许在运行时动态选择不同的实现,增强了程序的灵活性//简单工厂示例Animal getAnimalStringtype{if dog.equalstype returnnew Dog;else returnnew Cat;}多态使代码更加简洁优雅通过消除条件分支,提高了代码的可读性和可维护性例如,不使用多态时,我们可能需要大量的if-else语句来处理不同类型的对象;而使用多态,代码可以统一处理父类引用,JVM会自动调用正确的方法实现在现代企业应用开发中,多态是实现插件架构、可替换组件和依赖注入等高级设计的基础它使系统能够在不重新编译的情况下扩展功能,只需添加新的实现类这种灵活性对于构建可维护、可扩展的大型系统至关重要对象的生命周期创建不可达使用new关键字实例化对象对象不再有任何引用分配内存空间成为垃圾回收候选调用构造方法初始化等待JVM回收内存使用销毁通过引用访问对象垃圾回收器回收内存调用方法,修改状态可能调用finalize方法可能被多个引用指向对象被彻底清除对象的生命周期在Java中自动管理,开发者不需要显式销毁对象当对象不再被任何引用变量引用时,它将成为垃圾回收的候选者Java的垃圾回收器会在适当的时候自动回收这些对象占用的内存,这大大降低了内存泄漏的风险虽然finalize方法在对象被垃圾回收前调用,但不推荐依赖它来释放资源finalize方法调用的时间是不确定的,甚至可能不被调用对于需要显式关闭的资源(如文件、数据库连接),应使用try-with-resources或finally块确保资源正确释放在Java9中,finalize已被标记为过时deprecated,推荐使用Cleaner机制静态成员与类成员静态成员特点public classCounter{•使用static关键字修饰//静态变量(类变量)•属于类,而非对象实例private staticint count=0;•所有实例共享一份静态成员//实例变量•可通过类名直接访问,无需创建对象private Stringname;•在类加载时初始化,先于任何实例存在public CounterStringname{this.name=name;count++;//每创建一个实例,计数器加1}//静态方法public staticint getCount{return count;}//实例方法public StringgetName{return name;}}//使用示例Counter c1=new Counter一号;Counter c2=new Counter二号;System.out.printlnCounter.getCount;//输出2静态成员适用于需要在所有实例间共享的数据或行为常见用途包括计数器(记录创建了多少个对象)、常量定义(如Math.PI)、工具方法(不依赖实例状态的方法)和单例模式实现静态方法不能访问非静态成员,因为静态方法在对象创建前就可能被调用静态变量存储在方法区(Java8之前)或堆中的类数据中(Java8之后),而不是对象所在的堆区域这意味着即使没有创建任何对象,静态成员也可以使用静态导入(import static)允许直接使用其他类的静态成员,无需类名前缀,但过度使用可能导致代码可读性下降关键字用法this引用当前对象this用于明确引用当前实例,区分局部变量和成员变量,特别是当方法参数与成员变量同名时public voidsetNameString name{this.name=name;//this.name指向成员变量}调用其他构造方法在构造方法中使用this参数调用同一类的其他构造方法,实现构造方法链必须是构造方法的第一条语句public PersonStringname{thisname,0;//调用另一个构造方法}方法链式调用方法返回this可以支持链式方法调用,提高代码的流畅性和可读性,常见于构建器模式public PersonsetNameString name{this.name=name;return this;//返回当前对象}this关键字是Java中的一个隐式参数,每个非静态方法都能访问它代表调用当前方法的对象实例在大多数情况下,使用this是可选的,但当局部变量与成员变量同名时,使用this可以明确区分,避免歧义在构造方法重载的场景中,this调用帮助避免代码重复,实现构造方法的复用例如,可以设计一个完整的构造方法,其他构造方法通过this调用它,只需提供不同的默认值这种做法遵循DRY(Dont RepeatYourself)原则,使代码更易维护静态方法中不能使用this关键字,因为静态方法属于类,而不是对象实例包()与类组织package包的声明导入其他包使用package语句声明类所属的包,必须是使用import语句导入其他包中的类,简化类名Java文件的第一条语句引用编译与打包创建子包编译后在文件系统中创建对应的目录结构,可3使用点号.分隔包层次,形成树状结构组织打包为JAR文件包package是Java中组织类的机制,它提供了命名空间隔离,防止类名冲突,并支持访问控制良好的包结构应反映应用的逻辑组织,通常采用反向域名模式命名(如com.company.project.module),确保全局唯一性导入import简化了跨包类的引用可以导入单个类import java.util.ArrayList或整个包import java.util.*Java自动导入java.lang包,无需显式import导入静态成员import static允许直接使用其他类的静态字段和方法包的物理结构是目录层次,每个包对应一个目录,包名的点号在文件系统中表示为目录分隔符类文件与命名规则Java源文件.java包含Java源代码,文件名必须与public类名完全匹配编译过程javac编译器将源代码转换为字节码字节码文件.class每个类生成一个独立的字节码文件,包括内部类Java的命名规范是确保代码可读性和一致性的重要部分类名应使用驼峰命名法CamelCase,首字母大写,如StudentRecord;接口通常也遵循同样规则,有时添加前缀或后缀表明其性质,如Runnable,IMovable,PersonInterface包名应全部小写,使用点号分隔层次,通常采用反向域名模式,如com.company.project编译过程将创建与包结构对应的目录层次例如,包com.example.util中的Helper类在编译后会生成com/example/util/Helper.class文件一个.java源文件只能有一个public类,且文件名必须与该类名相同非public类可以有多个,它们也会各自生成.class文件运行Java程序时,JVM会根据类名和包名的组合完全限定名查找并加载对应的字节码文件对象数组与集合对象数组集合框架对象数组是存储同一类型对象引用的数组创建对象数组只是创建了一个引用数组,需要集合提供了更灵活的对象存储方式,支持动态增删、泛型类型安全、丰富的操作方法和多单独创建每个对象并赋值给数组元素种实现选择//创建对象数组//创建ArrayList集合Student[]students=new Student
[3];ArrayListStudent studentList=new ArrayList;//创建对象并赋值//添加对象students
[0]=new Student张三,18;studentList.addnew Student张三,18;students
[1]=new Student李四,19;studentList.addnew Student李四,19;students
[2]=new Student王五,20;//删除对象//访问对象studentList.remove1;//删除索引1的元素System.out.printlnstudents
[0].getName;//遍历对象for Students:studentList{System.out.printlns.getName;}相比于数组,Java集合框架提供了更多优势大小可动态调整、强大的API支持(如搜索、排序、过滤)、实现了面向接口编程(使用List接口而非具体实现)以及支持泛型保证类型安全常用的集合实现包括ArrayList(基于动态数组)、LinkedList(基于链表)、HashSet(无序集合)和HashMap(键值对映射)选择数组还是集合取决于具体需求当元素数量固定且需要最佳性能时,使用数组;当需要动态增删元素或利用丰富操作方法时,使用集合现代Java开发中,集合的使用频率远高于数组,特别是在处理复杂数据结构和业务逻辑时枚举类基本用法//定义枚举类public enumSeason{SPRING春天,温暖,SUMMER夏天,炎热,AUTUMN秋天,凉爽,WINTER冬天,寒冷;private finalString chineseName;private finalString description;//构造方法(隐式private)SeasonString chineseName,String description{this.chineseName=chineseName;this.description=description;}//getter方法public StringgetChineseName{return chineseName;}public StringgetDescription{return description;}}//使用枚举Season currentSeason=Season.SUMMER;System.out.println当前季节+currentSeason.getChineseName;类型安全值域限定枚举是类型安全的常量,编译器会检查使用的枚举值是否合法,避免无效枚举明确定义了允许的所有可能值,在需要表示有限集合的场景(如状态、值引发的错误选项等)非常有用功能丰富Java枚举是完整的类,可以有属性、方法、实现接口,比简单的常量集合功能更强大接口()及作用interface接口定义声明方法集合,定义规范而不实现public interfaceSwimmer{void swim;}类实现接口使用implements关键字,必须实现所有方法public classFish implementsSwimmer{public voidswim{...}}多态使用接口类型引用指向实现类对象Swimmer s=new Fish;接口interface是Java支持多重继承的机制,一个类只能继承一个父类,但可以实现多个接口接口定义了一组抽象行为,相当于一种契约,实现接口的类必须提供这些行为的具体实现接口成员默认是public的,字段默认是public staticfinal的,方法默认是public abstract的接口在软件设计中发挥着重要作用实现了面向接口编程原则,降低了组件之间的耦合;支持多态性,使得同一个接口可以有不同的实现;促进了代码的可扩展性,可以在不修改现有代码的情况下添加新功能自Java8起,接口可以包含默认方法default和静态方法,自Java9起,还可以包含私有方法,这些特性增强了接口的灵活性抽象类与接口的区别特性抽象类接口关键字abstract classinterface实现/继承extends(单继承)implements(可多实现)构造方法可以有构造方法不能有构造方法成员变量可以有成员变量(任何访问级别)只能有常量(public staticfinal)方法实现可以有抽象方法和具体方法Java8前只能有抽象方法,Java8后可有default和static方法访问修饰符可以使用任何访问修饰符方法默认public,不能用其他修饰符使用场景表示是一种关系,强调类的本质表示能做什么,强调行为能力抽象类和接口都是Java实现多态的重要机制,但它们有不同的设计目的和使用场景抽象类通常用于表示对象的抽象本质,适合类层次结构中的公共基类;而接口则侧重于定义对象的行为能力,适合不相关类实现共同行为在设计选择上,一个经验法则是当需要在多个不相关的类中共享某种能力时,使用接口;当需要为相关类提供基础实现或需要共享状态和行为时,使用抽象类Java8后接口可以有默认实现,这在一定程度上模糊了两者的界限,但它们的核心设计意图仍有差异实际应用中,常将两者结合使用,如抽象类实现接口,提供部分通用实现,再由具体子类完成剩余部分类与对象的实际案例//Person基类//Student子类public abstractclass Person{public classStudent extendsPerson{protected Stringname;private int studentId;protected int age;private String major;public PersonStringname,intage{public StudentStringname,intage,intstudentId,Stringmajor{this.name=name;supername,age;this.age=age;this.studentId=studentId;}this.major=major;}//抽象方法,子类必须实现public abstractvoid introduce;@Overridepublic voidintroduce{//共同方法System.out.println我是学生+name+,学号+studentId+public voidsleep{,专业是+major;System.out.printlnname+正在休息;}}public voidstudy{//getter和setter System.out.printlnname+正在学习+major;public StringgetName{return name;}}public voidsetNameString name{this.name=name;}public intgetAge{return age;}//getter和setterpublic voidsetAgeint age{this.age=age;}public intgetStudentId{return studentId;}}public voidsetStudentIdint studentId{this.studentId=studentId;}public StringgetMajor{return major;}public voidsetMajorString major{this.major=major;}}在这个学校管理系统案例中,Person是一个抽象基类,定义了人员的共同属性(姓名、年龄)和行为(介绍自己、休息)Student类继承自Person,添加了特定属性(学号、专业)和行为(学习),并实现了抽象方法introduce,体现了继承和多态的特性这种设计体现了面向对象的核心原则将共同特性抽象到基类,特定特性实现在子类使用这种方式,可以轻松扩展更多角色(如Teacher、Administrator等),每个角色都继承基本特性并添加特定功能,同时保持类型兼容性,便于统一管理不同类型的人员对象复杂对象属性对象组合对象引用领域建模一个类的对象作为另一个类的属性,形成有一个has-a关系,比如汽车有引擎、Java中,对象属性实际上是对其他对象的引用当一个对象包含对其他对象的引对象组合是领域驱动设计DDD中的关键概念,用于创建反映现实世界关系的对象车轮等这种组合关系通过将复杂系统分解为相互协作的组件,降低了系统复杂用时,需要确保这些被引用对象的正确初始化和生命周期管理模型通过合适的组合关系,可以使代码结构更接近问题域度//地址类public classAddress{private Stringstreet;private Stringcity;private StringzipCode;//构造方法、getter和setter略}//联系信息类public classContactInfo{private Stringemail;private Stringphone;//构造方法、getter和setter略}//学生类(包含复杂对象属性)public classStudent{private Stringname;private intid;private Addressaddress;//对象属性private ContactInfocontactInfo;//对象属性//构造方法、getter和setter略}类的嵌套与内部类成员内部类静态内部类局部内部类与匿名内部类定义在外部类内部的非静态类可以访问外部类的所有成员(包使用static修饰的内部类不需要外部类实例即可创建,无法访局部内部类定义在方法内部,作用范围仅限于该方法匿名内部括私有成员),通常用于实现与外部类紧密相关的功能每个成问外部类的实例成员,只能访问外部类的静态成员适用于外部类是没有名字的内部类,通常用于创建接口或抽象类的一次性实员内部类实例都与一个外部类实例关联类的辅助类,但不需要访问外部类实例状态现,如事件处理器、回调函数等public classOuter{public classOuter{button.addActionListenernew ActionListener{private intvalue;private staticint staticValue;public voidactionPerformedActionEvent e{public classInner{public staticclass StaticInner{System.out.printlnButton clicked;public voidshow{public voidshow{}System.out.printlnvalue;//可访问外部类私有成员System.out.printlnstaticValue;//只能访问静态成员};}}}}}}内部类提供了一种强大的封装机制,使得相关类可以紧密组织在一起,减少命名空间污染,提高代码组织性内部类可以访问外部类的成员,便于实现辅助功能;同时,外部类也可以访问内部类的private成员,实现双向访问在实际应用中,成员内部类常用于实现一个类内部的辅助功能,如结果集遍历器;静态内部类常用于表示与外部类相关但不依赖外部类实例的概念,如构建器Builder模式;匿名内部类则广泛用于GUI编程、集合处理、线程创建等需要简洁实现接口或抽象类的场景自Java8起,很多匿名内部类可以用Lambda表达式替代,代码更加简洁构造方法重载什么是构造方法重载构造方法重载是指在同一个类中定义多个名称相同但参数列表不同的构造方法这允许使用不同方式创建和初始化同一类的对象,提供了实例化对象的灵活性重载构造方法的原则参数数量不同、参数类型不同或参数顺序不同,都可以构成重载返回类型不能作为重载的区分条件(构造方法没有返回类型)构造方法通常按照参数复杂度从简单到复杂排列构造方法链使用this调用同一类中的其他构造方法,以减少代码重复this调用必须是构造方法的第一条语句常见模式是设计一个包含所有参数的主构造方法,其他构造方法通过this调用它,提供一些参数的默认值public classBook{private Stringtitle;private String author;private int pageCount;private double price;//全参数构造方法public BookStringtitle,String author,intpageCount,double price{this.title=title;this.author=author;this.pageCount=pageCount;this.price=price;}//带有默认页数的构造方法public BookStringtitle,String author,double price{thistitle,author,200,price;//调用全参数构造,默认200页}//只有书名和作者的构造方法public BookStringtitle,Stringauthor{thistitle,author,200,
29.99;//提供默认页数和价格}//默认构造方法public Book{this未知,佚名,100,
9.99;//提供所有默认值}//getter和setter方法略}方法重载()Overload方法重载的定义public classCalculator{方法重载是指在同一个类中定义多个名称相同但参数列表不同的方法编译器根据调用时提供的参数类型和数量决定执行哪个//整数加法方法方法重载提高了代码的可读性和灵活性,使得相似功能可以使用同一个方法名public intaddint a,int b{return a+b;重载的条件}•方法名必须相同//三个整数加法•参数列表必须不同(参数数量不同,或参数类型不同,或参数顺序不同)public intaddint a,int b,int c{•返回类型可以相同也可以不同,但不能仅靠返回类型区分重载方法return a+b+c;}//浮点数加法public doubleadddouble a,double b{return a+b;}//整数和浮点数加法public doubleaddint a,double b{return a+b;}//浮点数和整数加法(参数顺序不同)public doubleadddouble a,int b{return a+b;}}方法重载是静态多态(编译时多态)的一种形式,因为调用哪个重载方法是在编译时确定的,而非运行时这与方法重写(动态多态或运行时多态)不同,后者是在运行时根据对象的实际类型决定调用哪个方法Java根据最佳匹配原则选择重载方法,会进行一些自动类型转换(如int可以转为double)方法重载的常见应用场景包括提供不同参数组合的构造方法;根据不同参数类型提供相同功能(如各种数值类型的数学运算);支持不同数量的参数(如可变参数方法)重载使API更加直观和易用,同时保持命名一致性,避免为相似功能创建不同名称的方法类方法的调用流程实例方法调用需要先创建类的实例对象使用对象引用调用方法例如student.study;静态方法调用不需要创建类的实例直接通过类名调用例如Math.random;内部方法调用同一个类中的方法互相调用可以直接调用或使用this引用例如this.init或直接init;父类方法调用使用super关键字调用父类方法常见于方法重写场景例如super.toString;实例方法的调用需要通过对象引用访问,因为这些方法操作对象的状态(实例变量)JVM在调用实例方法时,会隐式传递当前对象的引用(this)作为方法的第一个参数实例方法在字节码层面实际上是接收对象引用作为参数的函数静态方法属于类而非对象,因此可以通过类名直接调用,无需创建实例静态方法不能访问非静态成员,因为它们在对象创建之前就可能被调用虽然也可以通过对象引用调用静态方法(如obj.staticMethod),但这不是推荐的做法,因为它可能导致误解,让人误以为静态方法与特定对象相关方法调用时,参数按值传递,对于基本类型传递值的副本,对于对象类型传递引用的副本类的类图简要说明UML类的表示关系表示工具UMLUML类图中,类用矩形表示,分为三个部分顶部继承关系用空心三角箭头指向父类的实线表示常用UML建模工具包括Enterprise Architect、是类名;中间是属性列表;底部是方法列表可以关联关系用普通箭头连接相关类聚合关系用Visual Paradigm、StarUML、Draw.io(在线工具)、使用符号表示可见性+public、-private、#空心菱形箭头表示整体-部分关系组合关系用IntelliJ IDEA/Eclipse(IDE内置UML插件)等这些protected、~包级私有实心菱形箭头表示更强的整体-部分关系,生命周工具可以帮助开发者创建、编辑和管理UML图,有期通常一致实现关系用空心三角箭头指向接口些还支持从UML生成代码或从代码生成UML的虚线表示UML统一建模语言类图是面向对象设计中表示类结构和关系的重要工具它提供了一种可视化方式,帮助开发者理解和交流系统的静态结构类图不仅显示类的内部结构(属性和方法),还展示了类之间的各种关系,如继承、实现、关联、聚合和组合在实际开发中,UML类图通常用于需求分析阶段捕获领域模型;设计阶段规划系统结构;文档化现有系统以便理解和维护;与团队成员和利益相关者交流设计决策虽然不需要严格遵循UML所有复杂符号,但掌握基本符号和概念对于有效表达面向对象设计至关重要类图是从宏观角度理解Java类关系的有力工具常见面试高频问题总结类和对象的区别封装的实现方式多态实现机制Java类是抽象的模板,定义了对象的结将属性声明为private,提供public的Java通过方法重写和向上转型实现多构;对象是类的具体实例,占用内getter和setter方法控制访问好处包态父类引用指向子类对象,调用存空间类比为蓝图与实际建筑的括数据保护、隐藏实现细节、提被子类重写的方法时,执行的是子关系,类在编译时确定,对象在运高灵活性(可以在方法中添加验证类版本运行时绑定(动态绑定)行时创建逻辑)是关键机制重载与重写的区别重载同一个类中,方法名相同,参数不同;编译时确定(静态绑定)重写子类覆盖父类方法,方法签名相同;运行时确定(动态绑定)在面试中,面向对象编程的概念常被重点考察除了上述问题,面试官还可能询问抽象类和接口的区别及使用场景;为什么Java不支持多重继承;this和super关键字的用法;Java中如何实现类似多重继承的功能;final关键字对类、方法和变量的影响;静态方法和实例方法的区别等回答这些问题时,不仅要准确解释概念,还应结合实际案例说明,展示对面向对象原则的深入理解例如,讨论封装时,可以举例说明如何通过private属性和setter方法添加数据验证;讨论多态时,可以解释它如何简化代码并提高扩展性理论与实践相结合的回答更能展示你的实际编程能力常见开发误区解析在面向对象编程中,常见的错误包括静态与实例成员混用,如在静态方法中直接访问非静态成员;构造器中存在复杂逻辑或调用可Java被重写的方法,导致子类初始化不完全;过度使用继承而非组合,创建过深的继承层次,增加耦合性;忽视封装原则,直接暴露成员变量或提供不安全的访问;创建过于庞大的上帝类,违反单一责任原则其他常见问题还有忘记正确释放资源(如数据库连接、文件流),应使用或块确保关闭;对象间循环引用导致的try-with-resources finally内存泄漏;滥用静态成员和单例模式,造成全局状态难以管理;继承时不遵循里氏替换原则,导致代码难以维护;频繁创建和丢弃短生命周期的大对象,增加垃圾回收压力通过代码审查、单元测试和遵循设计原则可以避免这些问题实践自定义一个商品类public classProduct{//私有属性private Stringname;private double price;private int stockQuantity;private String description;//构造方法public ProductStringname,doubleprice{this.name=name;this.price=price;this.stockQuantity=0;this.description=;}//全参数构造方法public ProductStringname,doubleprice,intstockQuantity,Stringdescription{this.name=name;this.price=price;this.stockQuantity=stockQuantity;this.description=description;}//打印商品信息的方法public voidprintInfo{System.out.println商品名称+name;System.out.println商品价格¥+price;System.out.println库存数量+stockQuantity;System.out.println商品描述+description;}//getter和setter方法public StringgetName{return name;}public voidsetNameString name{this.name=name;}public doublegetPrice{return price;}public voidsetPricedouble price{ifprice0{throw newIllegalArgumentException价格不能为负数;}this.price=price;}//其他getter和setter方法略}案例对象集结与团队建模//Person类//Team类public classPerson{public classTeam{private Stringid;private Stringname;private Stringname;private ArrayListPersonmembers;private String role;public TeamStringname{public PersonStringid,Stringname,Stringrole{this.name=name;this.id=id;this.members=new ArrayList;this.name=name;}this.role=role;}//添加成员public voidaddMemberPerson person{//getter和setter方法略members.addperson;}@Overridepublic StringtoString{//移除成员return Person{id=+id+public booleanremoveMemberString id{,name=+name+return members.removeIfp-p.getId.equalsid;,role=+role+};}}}//查找成员public PersonfindMemberString id{for Personp:members{if p.getId.equalsid{return p;}}return null;}//打印团队信息public voidprintTeamInfo{System.out.println团队名称:+name;System.out.println成员数量:+members.size;for Personp:members{System.out.println-+p;}}}与其他编程范式比较特性面向过程编程面向对象编程核心单元功能/函数对象/类数据组织数据与函数分离数据与方法封装在对象中程序结构自上而下,线性执行对象之间交互,消息传递代码重用通过函数调用通过继承和组合扩展性修改现有代码添加新类,不改变现有代码数据安全有限保护,全局数据容易被修改通过封装提供更好的数据保护典型语言C,Pascal,FORTRAN Java,C++,C#,Python面向对象编程与面向过程编程在思维方式上有根本区别面向过程编程关注如何一步步解决问题,程序由一系列操作步骤组成;而面向对象编程则关注谁来完成任务,将问题分解为协作的对象集合面向对象更接近人类认知世界的方式,通过抽象和封装管理复杂性面向对象编程相比面向过程编程有几个显著优势更好的模块化,降低代码耦合度;更高的代码重用率,通过继承和多态减少冗余;更好的可维护性,局部变化不影响整体;更强的问题抽象能力,能更自然地映射复杂问题域但面向对象也有一些挑战,如可能的性能开销、设计复杂度提高、学习曲线陡峭等实际项目中,常结合两种范式,取长补短行业应用与实例拓展亿65%2590%企业级应用设备运行财富强企业Java500Java凭借其稳定性和可靠性,成为企业级应用开发的首选语从服务器到移动设备,Java的一次编写,到处运行理念得绝大多数顶级企业使用Java开发关键业务系统言之一到广泛应用金融行业电子商务游戏开发银行系统利用Java面向对象特性,建立复杂的账户层电商平台使用对象模型表示商品、订单、用户等实游戏引擎中,角色、道具、场景等都是对象,通过次结构(储蓄账户、支票账户、贷款账户等),使体,利用继承创建各类商品体系,通过组合表示购继承实现不同角色类型,使用组合关系表示角色装用多态性处理不同类型交易,使用接口定义支付处物车与商品的关系,使用工厂模式和策略模式处理备,通过接口定义交互行为面向对象方法使得复理标准,同时通过封装保护敏感财务数据支付和配送等流程,体现了面向对象设计的灵活性杂的游戏世界可以被模块化管理,便于扩展和维护在实际应用中,面向对象编程与设计模式、架构模式等高级概念紧密结合例如,Spring框架大量使用依赖注入模式,降低对象间耦合;Hibernate利用对象关系映射,将数据库表映射为对象;Android应用开发中,各种组件都是基于对象模型资源推荐与后续学习路线权威书籍推荐在线资源与社区•《Java核心技术》(凯·S·霍斯特曼)-全面介绍Java基础知识•Oracle Java官方文档与教程•《Effective Java》(约书亚·布洛克)-Java最佳实践指南•Stack Overflow-编程问答社区•《深入理解Java虚拟机》(周志明)-JVM原理与调优•GitHub-开源项目与代码学习•《Java并发编程实战》-多线程与并发编程•Baeldung-高质量Java教程网站•《设计模式》(四人帮)-面向对象设计模式经典•InfoQ-软件开发资讯与文章•慕课网、极客时间-中文Java学习平台基础巩固深入理解面向对象概念、Java基础类库、异常处理、集合框架进阶学习Java多线程与并发、JVM原理、设计模式、反射与注解高级主题Spring框架、数据库编程、微服务架构、性能优化实战项目参与开源项目、构建个人作品集、解决实际业务问题持续学习是Java开发者职业发展的关键除了掌握技术知识外,参与实际项目练习、阅读优质源码、与社区交流都是提升能力的有效途径优质开源项目如Spring、Guava、Apache Commons等提供了学习Java最佳实践的绝佳材料结语拥抱面向对象,精通开发Java面向对象思维编码实践培养抽象思考能力,用对象视角分析问题坚持编写高质量、可维护的面向对象代码分享交流持续创新参与社区,共同提高关注新技术,不断更新知识库面向对象编程是现代软件开发的基石,它不仅是一种编程方法,更是一种思考问题和解决问题的方式通过本课程的学习,我们已经掌握了Java面向对象编程的核心概念,包括类与对象、封装、继承和多态等基础知识这些概念构成了理解更高级Java技术的基础在未来的学习和工作中,建议将面向对象原则融入到日常编程实践中,不断提升代码质量同时,保持对新技术的好奇心,学习设计模式、架构模式等高级知识,将使你的Java开发技能更上一层楼记住,优秀的开发者不仅掌握技术,还能够用面向对象的思维创造优雅、高效的解决方案。
个人认证
优秀文档
获得点赞 0