✨博客主页 https://blog.csdn.net/m0_63815035?typeblog《博客内容》大数据、AI开发、Java、测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识博客专栏https://blog.csdn.net/m0_63815035/category_11954877.html欢迎点赞 收藏 ⭐留言 本文为学习笔记资料如有侵权请联系我删除疏漏之处还请指正大厦之成非一木之材也大海之阔非一流之归也✨目录一、语言发展主线为什么需要对象二、类与对象1. 类的定义2. 对象的创建和使用3. 构造器Constructor4. this 关键字5. 内存分析简略三、封装1. 为什么要封装2. 访问控制符3. getter / setter4. JavaBean 规范四、继承1. 继承语法和特点2. 方法重写Override3. super 关键字4. 构造器调用顺序5. Object 类常用方法五、多态1. 多态的定义2. 注意点3. 向下转型4. 动态绑定机制六、抽象类与接口1. 抽象类2. 接口3. 接口 vs 抽象类Java 8 以前4. Java 8 之后的接口变化5. 面向接口编程七、内部类1. 成员内部类2. 静态内部类3. 局部内部类4. 匿名内部类八、类和类之间的关系九、设计原则SOLID 简版十、综合练习本篇是面向对象的完整讲解从类和对象开始到封装、继承、多态、接口、内部类最后涉及设计原则。每个概念都有例子和常见注意事项。一、语言发展主线为什么需要对象计算机语言发展本质上是为了更自然地表达人的思维同时管理越来越复杂的数据和操作。只有基本变量→ 能存单个数字、字符但数据一多就乱。数组→ 把同一类型的数据连续存放可以批量处理。但数组要求所有元素类型相同且只能存数据没有操作。结构体struct→ 允许把不同类型的数据如人的姓名、年龄、身高组合成一个整体。但数据和方法还是分开的。类和对象→ 把数据属性和操作方法绑在一起。一个对象就像现实中的一个实体有自己的状态和行为。面向过程数据和方法分离程序 数据结构 算法以函数为中心。面向对象数据和方法合一程序 对象 对象之间的消息传递以类/对象为中心。对于复杂系统比如一个电商平台宏观上需要用面向对象分析业务拆成用户、商品、订单等类但每个方法内部的具体实现如计算价格、校验库存仍然是面向过程的。二、类与对象1. 类的定义类是模板描述了一类事物共有的属性和方法。classStudent{// 属性成员变量实例变量intid;Stringname;intage;// 方法voidstudy(){System.out.println(name正在学习);}}属性可以设默认值不设则系统给默认值0、0.0、false、\u0000、null。方法定义和之前的函数一样只不过它属于类。2. 对象的创建和使用Students1newStudent();s1.id1001;s1.name张三;s1.study();new Student()在堆内存中开辟空间并返回地址给栈中的变量s1。每个对象有自己的属性副本互相独立。方法代码只存一份所有对象共享。3. 构造器Constructor构造器是创建对象时自动调用的特殊方法用来初始化对象。特点名字和类名完全相同没有返回值也不能写void不能被static、final、abstract修饰可以重载classStudent{intid;Stringname;// 无参构造Student(){System.out.println(调用无参构造);}// 有参构造Student(intid,Stringname){this.idid;// this 区分成员变量和局部变量this.namename;}}重要如果你不写任何构造器编译器会自动生成一个无参构造空实现。只要你写了任何带参构造编译器就不再自动生成无参构造。为了避免子类继承时出错建议手动把无参构造也写上。构造器之间可以用this(...)互相调用但必须放在第一行。Student(){this(0,无名);// 调用有参构造}4. this 关键字在构造器中表示正在初始化的对象。在实例方法中表示调用该方法的对象。不能出现在静态方法中因为静态方法不属于任何对象。常用场景区分成员变量和参数。调用另一个构造器必须第一行。返回当前对象链式调用。classCalculator{Calculatoradd(intx){// ... 运算returnthis;// 返回自身}}CalculatorcnewCalculator().add(5).add(3);5. 内存分析简略栈存放局部变量包括基本类型和对象引用方法调用时会压栈。线程私有速度较快。堆存放所有new出来的对象包括数组。线程共享速度稍慢。方法区存放类信息字节码、静态变量、字符串常量等。线程共享。StudentsnewStudent();加载Student.class到方法区。栈中创建s变量引用。堆中开辟一块空间存 Student 对象成员变量取默认值。执行构造器代码如果存在。将堆中对象的地址赋给s。三、封装1. 为什么要封装防止外部代码随意修改内部状态例如年龄不能为负数。隐藏实现细节外部只需知道调用什么方法不必关心内部如何实现。提高代码的可维护性修改内部逻辑不影响调用方。2. 访问控制符修饰符同类同包子类不同包任何地方private√(default)√√protected√√√public√√√√属性通常用private隐藏。方法一般用public向外提供服务。仅本类内部调用的辅助方法可以用private。3. getter / setterpublicclassPerson{privateStringname;privateintage;privatebooleanmarried;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){if(age0age150){this.ageage;}else{thrownewIllegalArgumentException(年龄非法);}}// 注意boolean 的 getter 习惯用 isXxxpublicbooleanisMarried(){returnmarried;}}4. JavaBean 规范一个标准的 JavaBean 需要类公开有无参构造属性私有提供 getter/setter实现Serializable可序列化后面再学封装不是简单的私有化而是提供合理的访问接口。四、继承1. 继承语法和特点classAnimal{Stringname;voideat(){System.out.println(吃东西);}}classDogextendsAnimal{voidbark(){System.out.println(汪汪);}}Java 只支持单继承一个类只能有一个直接父类但可以实现多接口。所有类除了Object都直接或间接继承Object。子类拥有父类所有的成员但private成员不能直接访问可以通过public或protected方法间接访问。2. 方法重写Override子类重新实现父类的方法。规则方法名、参数列表必须完全相同。返回值类型子类返回值类型可以是父类返回值类型的子类协变返回类型了解即可。访问权限不能更严格可以扩大不能缩小。private方法不能被重写static方法不能被重写但是可以重新声明。可以用Override注解让编译器帮你检查。classAnimal{protectedvoidshout(){System.out.println(动物叫);}}classCatextendsAnimal{Overridepublicvoidshout(){// protected - public 允许System.out.println(喵喵);}}3. super 关键字访问父类的属性当子类隐藏了父类同名属性时super.name调用父类的方法super.shout()调用父类的构造器super(...)必须出现在子类构造器的第一行。4. 构造器调用顺序创建子类对象时会先创建父类部分递归直到Object然后再执行子类构造器体的代码。子类构造器默认第一行有super()调用父类无参构造。如果父类没有无参构造子类构造器必须显式调用父类的有参构造。classFather{Father(intx){System.out.println(Father x);}}classSonextendsFather{Son(){super(100);// 必须写否则编译错误System.out.println(Son);}}5. Object 类常用方法toString()返回对象的字符串表示通常重写。equals(Object obj)判断对象是否相等默认比较地址通常需要重写。hashCode()返回对象的哈希码重写equals时必须重写hashCode。getClass()返回运行时类信息。OverridepublicStringtoString(){returnPerson{namename, ageage};}五、多态1. 多态的定义同一个类型的变量调用同一个方法实际执行的行为取决于运行时具体的对象类型。必要条件继承方法重写父类引用指向子类对象AnimalanewDog();// 向上转型自动a.shout();// 调用的是 Dog 的 shout()2. 注意点属性没有多态访问属性看编译时类型不是运行时类型。AnimalanewDog();System.out.println(a.age);// 还是 Animal 的 age静态方法没有多态静态方法属于类调用时看编译时类型。AnimalanewDog();a.staticMethod();// 调用的是 Animal 的静态方法3. 向下转型当你想调用子类特有的方法时需要把父类引用转回子类类型。AnimalanewDog();if(ainstanceofDog){// 安全检查避免 ClassCastExceptionDogd(Dog)a;d.bark();// Dog 独有的方法}instanceof关键字判断对象是否是某个类或其子类的实例。4. 动态绑定机制编译时编译器只检查引用变量的类型中是否有该方法。运行时JVM 会找到对象实际类型的方法表执行真正的方法。这就是多态的核心原理。六、抽象类与接口1. 抽象类当某个方法无法在父类中给出合理实现时可以声明为抽象方法要求子类必须实现。abstractclassShape{abstractdoublearea();// 抽象方法无方法体voidshow(){System.out.println(这是一个形状);}}有抽象方法的类必须声明为abstract。抽象类不能实例化不能new。抽象类可以有构造器供子类调用、普通属性、普通方法。子类必须实现所有抽象方法除非子类也是抽象类。2. 接口接口是完全抽象的规范强调“能做什么”。interfaceFlyable{intMAX_HEIGHT1000;// public static finalvoidfly();// public abstract}接口中的变量默认是public static final方法默认是public abstract。接口不能有构造器不能有实例属性但可以有静态常量。一个类可以实现多个接口多实现。实现类必须重写所有接口中的抽象方法且方法必须是public。classBirdimplementsFlyable{Overridepublicvoidfly(){System.out.println(鸟飞);}}3. 接口 vs 抽象类Java 8 以前特性抽象类接口多继承不支持支持类可多实现实例属性可以有只能有静态常量构造器可以有不能有访问权限可以任意方法默认 public使用场景表示“是什么”is-a表示“能做什么”can-do4. Java 8 之后的接口变化默认方法用default修饰可以有方法体实现类可以继承或重写。静态方法用static修饰属于接口通过接口名调用。interfaceVehicle{defaultvoidrun(){System.out.println(交通工具在跑);}staticvoidhonk(){System.out.println(嘀嘀);}}这些变化允许接口在不破坏已有实现类的情况下增加方法。5. 面向接口编程优先使用接口类型声明变量而不是具体类。这样更换实现不影响调用代码。ListStringlistnewArrayList();// 好// ArrayListString list new ArrayList(); // 不好耦合太强七、内部类内部类定义在另一个类内部可以更好地封装也能访问外部类的所有成员包括私有。1. 成员内部类classOuter{privateintx10;classInner{voidprint(){System.out.println(x);// 可以访问外部类私有成员}}}// 创建方法OuteroutnewOuter();Outer.Innerinout.newInner();成员内部类不能有静态成员除了静态常量。内部类中可以使用Outer.this访问外部类当前对象。2. 静态内部类classOuter{staticclassInner{}}// 创建Outer.InnerinnewOuter.Inner();不持有外部类对象的引用只能访问外部类的静态成员。可以像普通类一样有静态成员。3. 局部内部类定义在方法内部作用域仅限该方法。voidmethod(){classLocal{voidwork(){}}LocallnewLocal();}局部内部类可以访问外部类的成员也可以访问方法中的局部变量但局部变量必须是final或“实际上 final”JDK 8 后不需要显式写 final但不能修改。4. 匿名内部类最常用一次性使用无需命名。RunnablernewRunnable(){Overridepublicvoidrun(){System.out.println(run);}};匿名内部类继承某个类或实现某个接口不能同时做两件事。不能定义构造器。常用于事件监听、线程、回调等场景。button.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){// 处理点击}});八、类和类之间的关系关系描述UML 表示代码示例依赖一个类临时使用另一个类方法参数虚线箭头方法参数、局部变量关联一个类长期持有另一个类的引用实线箭头成员变量聚合整体与部分部分可独立存在空心菱形实线箭头成员变量弱组合整体与部分同生共死实心菱形实线箭头成员变量强继承is-a空心三角实线子类→父类extends实现类实现接口空心三角虚线类→接口implements聚合汽车和轮胎轮胎可以拆下来装在另一辆车上。组合人和心脏人没了心脏也就没了意义。九、设计原则SOLID 简版单一职责一个类只负责一项职责。开闭原则对扩展开放对修改关闭。增加功能尽量新增代码而不是改原有代码。里氏替换子类必须能替换父类并且程序行为正确。接口隔离接口应该小而专不要做“胖接口”。依赖倒置依赖抽象接口/抽象类不依赖具体实现。迪米特法则一个对象应尽可能少地了解其他对象。这些原则不是死的但遵循它们能让代码更容易维护和扩展。十、综合练习定义一个Point3D类三个坐标x,y,z提供构造器计算到原点的距离平方计算到另一个Point3D对象的距离平方。定义一个Circle类包含圆心Point和半径提供面积方法以及判断一个Point是否在圆内的方法。动物多态Animal抽象类shout()抽象方法。Dog、Cat继承并重写。用Animal引用调用shout()。接口练习定义USB接口含work()方法。实现Mouse和Keyboard类模拟将 USB 设备插入计算机。学习面向对象时多思考现实中的事物如何抽象成类类之间有哪些关系。代码写多了自然就会明白为什么需要封装、继承和多态。遇到不确定的就多翻 API 或写个小例子验证。今天这篇文章就到这里了大厦之成非一木之材也大海之阔非一流之归也。感谢大家观看本文
05 JAVA面向对象
发布时间:2026/6/8 14:23:07
✨博客主页 https://blog.csdn.net/m0_63815035?typeblog《博客内容》大数据、AI开发、Java、测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识博客专栏https://blog.csdn.net/m0_63815035/category_11954877.html欢迎点赞 收藏 ⭐留言 本文为学习笔记资料如有侵权请联系我删除疏漏之处还请指正大厦之成非一木之材也大海之阔非一流之归也✨目录一、语言发展主线为什么需要对象二、类与对象1. 类的定义2. 对象的创建和使用3. 构造器Constructor4. this 关键字5. 内存分析简略三、封装1. 为什么要封装2. 访问控制符3. getter / setter4. JavaBean 规范四、继承1. 继承语法和特点2. 方法重写Override3. super 关键字4. 构造器调用顺序5. Object 类常用方法五、多态1. 多态的定义2. 注意点3. 向下转型4. 动态绑定机制六、抽象类与接口1. 抽象类2. 接口3. 接口 vs 抽象类Java 8 以前4. Java 8 之后的接口变化5. 面向接口编程七、内部类1. 成员内部类2. 静态内部类3. 局部内部类4. 匿名内部类八、类和类之间的关系九、设计原则SOLID 简版十、综合练习本篇是面向对象的完整讲解从类和对象开始到封装、继承、多态、接口、内部类最后涉及设计原则。每个概念都有例子和常见注意事项。一、语言发展主线为什么需要对象计算机语言发展本质上是为了更自然地表达人的思维同时管理越来越复杂的数据和操作。只有基本变量→ 能存单个数字、字符但数据一多就乱。数组→ 把同一类型的数据连续存放可以批量处理。但数组要求所有元素类型相同且只能存数据没有操作。结构体struct→ 允许把不同类型的数据如人的姓名、年龄、身高组合成一个整体。但数据和方法还是分开的。类和对象→ 把数据属性和操作方法绑在一起。一个对象就像现实中的一个实体有自己的状态和行为。面向过程数据和方法分离程序 数据结构 算法以函数为中心。面向对象数据和方法合一程序 对象 对象之间的消息传递以类/对象为中心。对于复杂系统比如一个电商平台宏观上需要用面向对象分析业务拆成用户、商品、订单等类但每个方法内部的具体实现如计算价格、校验库存仍然是面向过程的。二、类与对象1. 类的定义类是模板描述了一类事物共有的属性和方法。classStudent{// 属性成员变量实例变量intid;Stringname;intage;// 方法voidstudy(){System.out.println(name正在学习);}}属性可以设默认值不设则系统给默认值0、0.0、false、\u0000、null。方法定义和之前的函数一样只不过它属于类。2. 对象的创建和使用Students1newStudent();s1.id1001;s1.name张三;s1.study();new Student()在堆内存中开辟空间并返回地址给栈中的变量s1。每个对象有自己的属性副本互相独立。方法代码只存一份所有对象共享。3. 构造器Constructor构造器是创建对象时自动调用的特殊方法用来初始化对象。特点名字和类名完全相同没有返回值也不能写void不能被static、final、abstract修饰可以重载classStudent{intid;Stringname;// 无参构造Student(){System.out.println(调用无参构造);}// 有参构造Student(intid,Stringname){this.idid;// this 区分成员变量和局部变量this.namename;}}重要如果你不写任何构造器编译器会自动生成一个无参构造空实现。只要你写了任何带参构造编译器就不再自动生成无参构造。为了避免子类继承时出错建议手动把无参构造也写上。构造器之间可以用this(...)互相调用但必须放在第一行。Student(){this(0,无名);// 调用有参构造}4. this 关键字在构造器中表示正在初始化的对象。在实例方法中表示调用该方法的对象。不能出现在静态方法中因为静态方法不属于任何对象。常用场景区分成员变量和参数。调用另一个构造器必须第一行。返回当前对象链式调用。classCalculator{Calculatoradd(intx){// ... 运算returnthis;// 返回自身}}CalculatorcnewCalculator().add(5).add(3);5. 内存分析简略栈存放局部变量包括基本类型和对象引用方法调用时会压栈。线程私有速度较快。堆存放所有new出来的对象包括数组。线程共享速度稍慢。方法区存放类信息字节码、静态变量、字符串常量等。线程共享。StudentsnewStudent();加载Student.class到方法区。栈中创建s变量引用。堆中开辟一块空间存 Student 对象成员变量取默认值。执行构造器代码如果存在。将堆中对象的地址赋给s。三、封装1. 为什么要封装防止外部代码随意修改内部状态例如年龄不能为负数。隐藏实现细节外部只需知道调用什么方法不必关心内部如何实现。提高代码的可维护性修改内部逻辑不影响调用方。2. 访问控制符修饰符同类同包子类不同包任何地方private√(default)√√protected√√√public√√√√属性通常用private隐藏。方法一般用public向外提供服务。仅本类内部调用的辅助方法可以用private。3. getter / setterpublicclassPerson{privateStringname;privateintage;privatebooleanmarried;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){if(age0age150){this.ageage;}else{thrownewIllegalArgumentException(年龄非法);}}// 注意boolean 的 getter 习惯用 isXxxpublicbooleanisMarried(){returnmarried;}}4. JavaBean 规范一个标准的 JavaBean 需要类公开有无参构造属性私有提供 getter/setter实现Serializable可序列化后面再学封装不是简单的私有化而是提供合理的访问接口。四、继承1. 继承语法和特点classAnimal{Stringname;voideat(){System.out.println(吃东西);}}classDogextendsAnimal{voidbark(){System.out.println(汪汪);}}Java 只支持单继承一个类只能有一个直接父类但可以实现多接口。所有类除了Object都直接或间接继承Object。子类拥有父类所有的成员但private成员不能直接访问可以通过public或protected方法间接访问。2. 方法重写Override子类重新实现父类的方法。规则方法名、参数列表必须完全相同。返回值类型子类返回值类型可以是父类返回值类型的子类协变返回类型了解即可。访问权限不能更严格可以扩大不能缩小。private方法不能被重写static方法不能被重写但是可以重新声明。可以用Override注解让编译器帮你检查。classAnimal{protectedvoidshout(){System.out.println(动物叫);}}classCatextendsAnimal{Overridepublicvoidshout(){// protected - public 允许System.out.println(喵喵);}}3. super 关键字访问父类的属性当子类隐藏了父类同名属性时super.name调用父类的方法super.shout()调用父类的构造器super(...)必须出现在子类构造器的第一行。4. 构造器调用顺序创建子类对象时会先创建父类部分递归直到Object然后再执行子类构造器体的代码。子类构造器默认第一行有super()调用父类无参构造。如果父类没有无参构造子类构造器必须显式调用父类的有参构造。classFather{Father(intx){System.out.println(Father x);}}classSonextendsFather{Son(){super(100);// 必须写否则编译错误System.out.println(Son);}}5. Object 类常用方法toString()返回对象的字符串表示通常重写。equals(Object obj)判断对象是否相等默认比较地址通常需要重写。hashCode()返回对象的哈希码重写equals时必须重写hashCode。getClass()返回运行时类信息。OverridepublicStringtoString(){returnPerson{namename, ageage};}五、多态1. 多态的定义同一个类型的变量调用同一个方法实际执行的行为取决于运行时具体的对象类型。必要条件继承方法重写父类引用指向子类对象AnimalanewDog();// 向上转型自动a.shout();// 调用的是 Dog 的 shout()2. 注意点属性没有多态访问属性看编译时类型不是运行时类型。AnimalanewDog();System.out.println(a.age);// 还是 Animal 的 age静态方法没有多态静态方法属于类调用时看编译时类型。AnimalanewDog();a.staticMethod();// 调用的是 Animal 的静态方法3. 向下转型当你想调用子类特有的方法时需要把父类引用转回子类类型。AnimalanewDog();if(ainstanceofDog){// 安全检查避免 ClassCastExceptionDogd(Dog)a;d.bark();// Dog 独有的方法}instanceof关键字判断对象是否是某个类或其子类的实例。4. 动态绑定机制编译时编译器只检查引用变量的类型中是否有该方法。运行时JVM 会找到对象实际类型的方法表执行真正的方法。这就是多态的核心原理。六、抽象类与接口1. 抽象类当某个方法无法在父类中给出合理实现时可以声明为抽象方法要求子类必须实现。abstractclassShape{abstractdoublearea();// 抽象方法无方法体voidshow(){System.out.println(这是一个形状);}}有抽象方法的类必须声明为abstract。抽象类不能实例化不能new。抽象类可以有构造器供子类调用、普通属性、普通方法。子类必须实现所有抽象方法除非子类也是抽象类。2. 接口接口是完全抽象的规范强调“能做什么”。interfaceFlyable{intMAX_HEIGHT1000;// public static finalvoidfly();// public abstract}接口中的变量默认是public static final方法默认是public abstract。接口不能有构造器不能有实例属性但可以有静态常量。一个类可以实现多个接口多实现。实现类必须重写所有接口中的抽象方法且方法必须是public。classBirdimplementsFlyable{Overridepublicvoidfly(){System.out.println(鸟飞);}}3. 接口 vs 抽象类Java 8 以前特性抽象类接口多继承不支持支持类可多实现实例属性可以有只能有静态常量构造器可以有不能有访问权限可以任意方法默认 public使用场景表示“是什么”is-a表示“能做什么”can-do4. Java 8 之后的接口变化默认方法用default修饰可以有方法体实现类可以继承或重写。静态方法用static修饰属于接口通过接口名调用。interfaceVehicle{defaultvoidrun(){System.out.println(交通工具在跑);}staticvoidhonk(){System.out.println(嘀嘀);}}这些变化允许接口在不破坏已有实现类的情况下增加方法。5. 面向接口编程优先使用接口类型声明变量而不是具体类。这样更换实现不影响调用代码。ListStringlistnewArrayList();// 好// ArrayListString list new ArrayList(); // 不好耦合太强七、内部类内部类定义在另一个类内部可以更好地封装也能访问外部类的所有成员包括私有。1. 成员内部类classOuter{privateintx10;classInner{voidprint(){System.out.println(x);// 可以访问外部类私有成员}}}// 创建方法OuteroutnewOuter();Outer.Innerinout.newInner();成员内部类不能有静态成员除了静态常量。内部类中可以使用Outer.this访问外部类当前对象。2. 静态内部类classOuter{staticclassInner{}}// 创建Outer.InnerinnewOuter.Inner();不持有外部类对象的引用只能访问外部类的静态成员。可以像普通类一样有静态成员。3. 局部内部类定义在方法内部作用域仅限该方法。voidmethod(){classLocal{voidwork(){}}LocallnewLocal();}局部内部类可以访问外部类的成员也可以访问方法中的局部变量但局部变量必须是final或“实际上 final”JDK 8 后不需要显式写 final但不能修改。4. 匿名内部类最常用一次性使用无需命名。RunnablernewRunnable(){Overridepublicvoidrun(){System.out.println(run);}};匿名内部类继承某个类或实现某个接口不能同时做两件事。不能定义构造器。常用于事件监听、线程、回调等场景。button.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){// 处理点击}});八、类和类之间的关系关系描述UML 表示代码示例依赖一个类临时使用另一个类方法参数虚线箭头方法参数、局部变量关联一个类长期持有另一个类的引用实线箭头成员变量聚合整体与部分部分可独立存在空心菱形实线箭头成员变量弱组合整体与部分同生共死实心菱形实线箭头成员变量强继承is-a空心三角实线子类→父类extends实现类实现接口空心三角虚线类→接口implements聚合汽车和轮胎轮胎可以拆下来装在另一辆车上。组合人和心脏人没了心脏也就没了意义。九、设计原则SOLID 简版单一职责一个类只负责一项职责。开闭原则对扩展开放对修改关闭。增加功能尽量新增代码而不是改原有代码。里氏替换子类必须能替换父类并且程序行为正确。接口隔离接口应该小而专不要做“胖接口”。依赖倒置依赖抽象接口/抽象类不依赖具体实现。迪米特法则一个对象应尽可能少地了解其他对象。这些原则不是死的但遵循它们能让代码更容易维护和扩展。十、综合练习定义一个Point3D类三个坐标x,y,z提供构造器计算到原点的距离平方计算到另一个Point3D对象的距离平方。定义一个Circle类包含圆心Point和半径提供面积方法以及判断一个Point是否在圆内的方法。动物多态Animal抽象类shout()抽象方法。Dog、Cat继承并重写。用Animal引用调用shout()。接口练习定义USB接口含work()方法。实现Mouse和Keyboard类模拟将 USB 设备插入计算机。学习面向对象时多思考现实中的事物如何抽象成类类之间有哪些关系。代码写多了自然就会明白为什么需要封装、继承和多态。遇到不确定的就多翻 API 或写个小例子验证。今天这篇文章就到这里了大厦之成非一木之材也大海之阔非一流之归也。感谢大家观看本文