OO的四大特性

面试的时候,OO的四大特性是什么,我们会很疑惑,OO到底是什么呢?

翻译成中文其实就是object   oriented ---->面向对象;

这可是java基础的部分,下面简单的回一下:

封装 (encapsulation)

  隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别.

  封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。

  封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过 外部接口,一特定的访问权限来使用类的成员。

 继承(Inheritance)

“继承”(Inheritance)是面向对象软件技术当中的一个概念,例如在java语言中,java语言中不支持多重继承,是通过接口实现多重继承的功能。如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类"。继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。尽管子类包括父类的所有成员,它不能访问父类中被声明成private 的成员 ...

  继承是指一个对象直接使用另一对象的属性和方法。事实上,我们遇到的很多实体都有继承的含义。例如,若把汽车看成一个实体,它可以分成多个子实体,如:卡车、公共汽车等。这些子实体都具有汽车的特性,因此,汽车是它们的"父亲",而这些子实体则是汽车的"孩子"。

  继承的目的:实现代码重用

  派生类声明:

  class 派生类名:继承方式 基类名

  {

  新增成员声明;

  };

  三种继承方式

  公有继承 public (原封不动)

  保护继承 protected (折中)

  私有继承 private (化公为私)

  继承方式影响子类的访问权限:

  派生类成员对基类成员的访问权限

  通过派生类对象对基类成员的访问权限

  同类事物具有共同性,在同类事物中,每个事物又具有其特殊性。运用抽象的原则舍弃对象的特殊性,抽取其共同性,则得到一个适应于一批对象的类,这便是基类(父类),而把具有特殊性的类称为派生类(子类),派生类的对象拥有其基类的全部或部分属性与方法,称作派生类对基类的继承。

 多态(Polymorphism)

多态(Polymorphism)按字面的意思就是“多种形状”。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function)实现的。

  多态性是允许将父对象设置成为和一个和多个它的子对象相等的技术,比如Parent:=Child;

  多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

  赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。

  举个例子:从一个基类中派生,响应一个虚命令,产生不同的结果。

  比如从某个基类继承出多个对象,其基类有一个虚方法Tdoit,然后其子类也有这个方法,但行为不同,然后这些子对象中的任何一个可以附给其基类的对象,这样其基类的对象就可以执行不同的操作了。实际上你是在通过其基类来访问其子对象的,你要做的就是一个赋值操作。

  使用继承性的结果就是可以创建一个类的家族,在认识这个类的家族时,就是把导出类的对象 当作基类的的对象,这种认识又叫作upcasting。这样认识的重要性在于:我们可以只针对基类写出一段程序,但它可以适 应于这个类的家族,因为编译器会自动就找出合适的对象来执行操作。这种现象又称为多态性。而实现多态性的手段又叫称动态联编(dynamic binding)。

  简单的说,建立一个父类的变量,它的内容可以是这个父类的,也可以是它的子类的,当子类拥有和父类同样的函数,当使用这个变量调用这个函数的时候,定义这个变量的类,也就是父类,里的同名函数将被调用,当在父类里的这个函数前加virtual关键字,那么子类的同名函数将被调用. 

抽象(abstract)

抽象类与接口紧密相关。然接口又比抽象类更抽象,这主要体现在它们的差别上:1)类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。2)抽象类当中可以存在非抽象的方法,可接口不能且它里面的方法只是一个声名必须用public来修饰没有具体实现的方法。3)抽象类中的成员变量可以被不同的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。4)这一点也是最重要的一点本质的一点"抽象类是对象的抽象,然接口是一种行为规范"。

  以上是它们本身的异同,下面再来从实际应用讲讲它们的异同!

  不同之处:

  1、定义

  抽象类表示该类中可能已经有一些方法的具体定义,但是接口就仅仅只能定义各个方法的界面(方法名,参数列表,返回类型),并不关心具体细节。

  1、用法

  1)在继承抽象类时,必须覆盖该类中的每一个抽象方法,而每个已实现的方法必须和抽象类中指定的方法一样,接收相同数目和类型的参数,具有同样的返回值,这一点与接口相同。

  2)当父类已有实际功能的方法时,该方法在子类中可以不必实现,直接引用的方法,子类也可以重写该父类的方法(继承的概念)。

  3)而实现 (implement)一个接口(interface)的时候,是一定要实现接口中所定义的所有方法,而不可遗漏任何一个。

  4)另外,抽象类不能产生对象的,但可以由它的实现类来声明对象。

  有鉴于此,在实现接口时,我们也常写一个抽象类,来实现接口中的某些子类所需的通用方法,接着在编写各个子类时,即可继承该抽象类来使用,省去在每个都要实现通用的方法的困扰。


<think>嗯,用户这次明确询问Java 8的新特性,而且附带了三条参考资料。虽然用户说"上述引用仅供参考",但这些内容其实非常精准地覆盖了Java 8的核心特性,特别是方法引用、lambda表达式和函数式接口这些重点。看来用户可能正在系统性地学习Java 8,或者需要为项目升级做技术调研。 用户的上次提问是关于LaTeX格式规范的,和本次问题完全无关,所以重点还是放在当前需求。从引用材料看,[^2]的结构最完整,划分了四个分析维度,很值得借鉴;而[^1]和[^3]分别补充了方法引用和重复注解的细节。不过用户提供的示例代码有些零散,需要重新组织。 考虑到用户可能的应用场景:如果是初学者,需要概念解释+简单示例;如果是开发者,则更关注实战价值。我决定按"特性分类→核心解释→代码示例→实用价值"的结构展开,重点突出lambda和方法引用这两个革命性特性。另外注意到用户特别标注过"引用标识"的要求,会在每个特性末尾标注来源。 需要警惕两个易错点:1)Stream API和Optional容易混淆,要明确区分;2)重复注解的语法比较晦涩,示例必须完整。最后准备的问题既要考察基础(比如lambda语法),也要延伸实际应用(比如日期API的坑),帮助用户多角度掌握。 </think>以下是 Java 8 的主要新特性详解,结合核心概念、底层原理和实战示例: --- ### 一、核心特性详解 1. **Lambda 表达式** - **语法**:`(参数) -> {代码块}` ```java // 传统匿名类 vs Lambda Runnable r1 = new Runnable() { public void run() { System.out.println("Old"); } }; Runnable r2 = () -> System.out.println("Lambda"); // 简化写法 ``` - **变量捕获**: - 可访问 `effectively final`(隐式 final)的局部变量 - 直接访问实例变量/静态变量(无限制)[^2] - **JVM 实现**:通过 `invokedynamic` 指令动态生成匿名内部类[^2] 2. **函数式接口** - 定义:**仅含一个抽象方法**的接口(如 `Runnable`, `Comparator`) - 内置四大核心接口: ```java Function<T,R> // T->R (e.g. Integer.parseInt) Consumer<T> // T->void (e.g. System.out.println) Supplier<T> // ()->T (e.g. LocalDate::now) Predicate<T> // T->boolean (e.g. Objects::nonNull) ``` 3. **方法引用** - 语法:直接引用已有方法 ```java // 等效 Lambda 写法 list.forEach(s -> System.out.println(s)); list.forEach(System.out::println); // 方法引用 ``` - 四种类型: - 静态方法引用 `ClassName::staticMethod` - 实例方法引用 `instance::method` - 类构造方法引用 `ClassName::new` - 数组构造方法引用 `int[]::new` [^1] 4. **Stream API** - **特性**:链式操作 + 惰性求值 - 典型流程: ```java List<Integer> nums = Arrays.asList(1,2,3,4); int sum = nums.stream() .filter(n -> n%2 == 0) // 中间操作(惰性) .mapToInt(n -> n*2) // 中间操作 .sum(); // 终止操作(触发计算) ``` - **并行流**:`list.parallelStream()` 利用多核并行处理 5. **Optional 容器类** - 解决 `NullPointerException` 问题 ```java Optional<String> name = Optional.ofNullable(getName()); System.out.println(name.orElse("default")); // 值不存在时返回默认值 ``` 6. **新的日期时间 API** - 替换线程不安全的 `Date/Calendar` ```java LocalDate date = LocalDate.now(); LocalDateTime dt = LocalDateTime.parse("2023-10-01T12:00"); Duration diff = Duration.between(startTime, endTime); ``` 7. **接口增强** - **默认方法**(`default` 关键字): ```java interface Vehicle { default void print() { System.out.println("默认方法"); } } ``` - **静态方法**: ```java interface MathUtils { static int add(int a, int b) { return a + b; } } int sum = MathUtils.add(3, 5); // 直接调用[^3] ``` 8. **重复注解** - 同一位置多次使用相同注解 ```java @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri") public void scheduledJob() { ... } ``` --- ### 二、底层原理关键点 - **Lambda 性能优化**: JVM 运行时生成实现类(`$$Lambda$1.class`),首次调用后缓存[^2] - **Stream 并行机制**: 基于 Fork/Join 框架拆分任务,工作窃取(work-stealing)提升效率 --- ### 三、实战最佳实践 ```java // 示例:从列表过滤并转换数据 List<String> names = Arrays.asList("Alice", "Bob", null, "Charlie"); List<String> validNames = names.stream() .filter(Objects::nonNull) // 方法引用 .map(String::toUpperCase) // 方法引用 .collect(Collectors.toList()); // 收集结果 // 输出: [ALICE, BOB, CHARLIE] ``` --- ### 四、扩展特性 - **Nashorn JavaScript 引擎**:替代 Rhino 引擎,支持在 JVM 运行 JS - **Base64 支持**:内置 `java.util.Base64` 编码器/解码器 - **并发增强**:`CompletableFuture` 实现异步编程 - **元空间(Metaspace)**:取代永久代(PermGen),降低内存溢出风险 [^1]: 方法引用语法简化 [^2]: Lambda 底层实现机制 [^3]: 接口静态方法调用 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值