惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
博客园 - Franky
MyScale Blog
MyScale Blog
Jina AI
Jina AI
B
Blog
Microsoft Security Blog
Microsoft Security Blog
T
Troy Hunt's Blog
博客园_首页
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
Lohrmann on Cybersecurity
GbyAI
GbyAI
T
Tenable Blog
B
Blog RSS Feed
S
Securelist
T
Threat Research - Cisco Blogs
P
Privacy International News Feed
P
Proofpoint News Feed
T
The Exploit Database - CXSecurity.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网
C
CXSECURITY Database RSS Feed - CXSecurity.com
罗磊的独立博客
AWS News Blog
AWS News Blog
V
V2EX
宝玉的分享
宝玉的分享
J
Java Code Geeks
小众软件
小众软件
Spread Privacy
Spread Privacy
腾讯CDC
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
V
Visual Studio Blog
The Hacker News
The Hacker News
C
CERT Recently Published Vulnerability Notes
Project Zero
Project Zero
Know Your Adversary
Know Your Adversary
T
The Blog of Author Tim Ferriss
Last Week in AI
Last Week in AI
Apple Machine Learning Research
Apple Machine Learning Research
NISL@THU
NISL@THU
C
Check Point Blog
Webroot Blog
Webroot Blog
D
DataBreaches.Net
Cloudbric
Cloudbric
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家

Java技术经验分享

生产故障处理SOP分享 | Java技术经验分享 系统稳定性建设实践总结【转载】 | Java技术经验分享 valine访问leancloud国际版异常,评论失效修复 | Java技术经验分享 匆匆忙忙的2021 | Java技术经验分享 聊一下换工作 | Java技术经验分享 IoT系列(2):WIFI设备常见配网方案介绍 | Java技术经验分享 IoT系列(1):什么是物联网 | Java技术经验分享 Java8特性2 - StreamApi | Java技术经验分享 Java8特性1 - lambda表达式&函数式接口 | Java技术经验分享 设计模式(5)-适配器模式 | Java技术经验分享 设计模式(4)-建造者模式 | Java技术经验分享 设计模式(3)-原型模式与浅拷贝和深拷贝 | Java技术经验分享 设计模式(2)-工厂模式图文介绍 | Java技术经验分享 设计模式(1)-带你了解3类8种单例模式 | Java技术经验分享 Java时间处理5---Java8中时区相关类库介绍 | Java技术经验分享 Java时间处理4---Java8中LocalDate、LocalTime、LocalDateTime介绍 | Java技术经验分享 Java时间处理3---Java8中Instant、Duration、Period、Clock介绍 | Java技术经验分享 一些有意思的问答 | Java技术经验分享 Nacos系列博客说明 | Java技术经验分享 菜鸡程序员的2019年度总结 | Java技术经验分享 Java中“附近的人”实现方案讨论及代码实现 | Java技术经验分享 Java时间处理2----时区TimeZone类方法探究(Java8以前) | Java技术经验分享 Java时间处理1----Date和Calendar方法探究(Java8以前) | Java技术经验分享 FastJson中JSONString、JavaBean、JSONObject、JSONArray的转换关系及API示例 | Java技术经验分享 2019.11软考软件设计师归来心得体会及复习备考指南 | Java技术经验分享 你还没用过“约定式提交”吗?那你赶紧来补补知识吧 | Java技术经验分享 教你如何看懂UML中的类图及类图中的关系 | Java技术经验分享 设计模式总览 | Java技术经验分享 萌新入门Github请看这里,学不会远程教 | Java技术经验分享 Hexo的工作原理探究 | Java技术经验分享 Hexo-theme-butterfly修改调整记录教程 | Java技术经验分享 排序8:基数排序 | Java技术经验分享 排序7:归并排序 | Java技术经验分享 排序6:快速排序 | Java技术经验分享 排序5:冒泡排序 | Java技术经验分享 排序4:堆排序 | Java技术经验分享 排序3:选择排序 | Java技术经验分享 排序2:希尔排序 | Java技术经验分享 排序1:直接插入排序 | Java技术经验分享 推荐一款博客一文多发的良心工具OpenWrite | Java技术经验分享 近期学习计划 | Java技术经验分享 Nacos(九):Nacos集群部署和遇到的问题 | Java技术经验分享 Nacos(八):Nacos持久化 | Java技术经验分享 Nacos(七):Nacos共享配置 | Java技术经验分享 Nacos(六):多环境下如何“管理”及“隔离”配置和服务 | Java技术经验分享 Nacos(五):多环境下如何“读取”Nacos中相应的配置 | Java技术经验分享 Nacos(四):SpringCloud项目中接入Nacos作为配置中心 | Java技术经验分享 Nacos(三):Nacos与OpenFeign的对接使用 | Java技术经验分享 Nacos(二):SpringCloud项目中接入Nacos作为注册中心 | Java技术经验分享 Nacos(一):Nacos介绍 | Java技术经验分享 20190719小组分享 | Java技术经验分享 Java中equals和HashCode方法的分析 | Java技术经验分享 Java中==和equals方法的分析 | Java技术经验分享 Java中的自动拆装箱、装箱缓存 | Java技术经验分享 About-blog | Java技术经验分享 Java中的编译、反编译和反编译工具全家桶分享 | Java技术经验分享 finalize()的生命周期(执行过程) | Java技术经验分享 Java关键字之final、finally与finalize方法 | Java技术经验分享 Java中重写、重载 | Java技术经验分享 DockerFile介绍 | Java技术经验分享 Docker环境下安装Gitlab | Java技术经验分享 Docker中私有仓库的搭建流程 | Java技术经验分享 Centos7下两种方式安装Docker-CE | Java技术经验分享 Vert.x创建一个Http服务 | Java技术经验分享 Vert.x创建TCP服务端及客户端 | Java技术经验分享 Vert.x Core(二)- Event Bus(事件总线) | Java技术经验分享 Vert.x-Core(一)- 基础篇 | Java技术经验分享 SpringBoot项目中实现国际化 | Java技术经验分享 Vert.x介绍 | Java技术经验分享 毕设选题项目本地运行环境搭建教程 | Java技术经验分享 Jupyter Notebooks的安装和使用介绍 | Java技术经验分享 算法笔试题:1元,5元,10元,20元,50元、100元面值人民币组合给定x元的问题 | Java技术经验分享 Quartz学习总结 | Java技术经验分享 SpringBoot2.x集成Redis | Java技术经验分享 SpringBoot2.x集成MongoDB | Java技术经验分享 [SpringCloud学习] - 浅谈微服务架构 | Java技术经验分享 基于hexo和coding免费搭建个人博客网站 | Java技术经验分享 Hello World | Java技术经验分享
Java中面向对象的三大特征:继承、封装、多态 | Java技术经验分享
文章作者: LarsCheng · 2019-05-23 · via Java技术经验分享

面向对象的三大特征

继承、封装、多态

接口(Interface)是用来定义行为的!

抽象类(Abstract Class)是用来实现行为的!

具体类(Class)是用来执行行为的!

使用了对象就叫基于对象,基于对象的基础上增加了继承从而变成了面向对象。

封装

是对象和类概念的主要特征

封装:即把客观事物封装成抽象的类,并且类可以对自己的数据和方法进行权限控制,

封装就是指利用抽象数据类型将数据和基于数据的操作封装在一起,数据被保护在抽象类型的内部,系统的其他部分只有通过包裹在数据外面的被授权的操作,才能够与这个抽象数据类型交流与交互!

封装的优点

  1. 将变化隔离
  2. 便于使用
  3. 提高安全性
  4. 提高重用性

总结

封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。

继承

继承:
继承是使用已存在的类的定义作为基础建立新的类,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码,能够大大的提高开发的效率。

继承的特点:

  1. 子类拥有父类非private的属性和方法。
  2. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
  3. 子类可以用自己的方式实现父类的方法。(重写)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Father父类
class Father {

public String name;

private int money;

public Father() {
this.name = "李明";
this.money = 1000;
}

public String getName() {
return name;
}

public Father setName(String name) {
this.name = name;
return this;
}

public int getMoney() {
return money;
}

public Father setMoney(int money) {
this.money = money;
return this;
}

public void say(){
System.out.println("我是父亲");
}

public void speak(){
System.out.println("父亲是我");
}
}

子类Son继承父类Father
class Son extends Father{

public String sonName;

public Son() {
this.sonName = "李小明";
}


@Override
public void say(){

System.out.println("我的父亲是:"+name+"他的存款我不知道...");

System.out.println("我的父亲是:"+getName()+"但他的存折显示存款为:"+getMoney());
}

public void speak(int age){
System.out.println("我的名字是:"+sonName+",年龄:"+age);
}
}

public class Test{

public static void main(String[] args){
Son s = new Son();
s.say();
s.speak(20);
}
}

执行结果:

1
2
3
我的父亲是:李明,他的存款我不知道...
我的父亲是:李明,但他的存折显示存款为:1000
我的名字是:李小明,年龄:20

栗子分析:
父类Father有自己的公有属性name,私有属性money,同时对外提供了所有属性的公有方法(get/set)

子类Son继承父类Father后,拥有父类所有非private的属性和方法的访问权限,子类Son同时还可以有自己的属性(sonName),儿子知道父亲的名字却不知道父亲具体的存款,但是可以通过从父类继承的getMoney()获取存折中的存款信息。

子类可以重写父类的方法,Son类对父类的say方法在保持方法名、参数列表、返回值不变的情况下,对具体的实现进行重写。

父类引用指向子类对象

保持上边代码中Father、Son的内容不变,修改Test类的内容如下:

1
2
3
4
5
6
7
8
public class Test{
public static void main(String[] args){

Father s = new Son();
s.say();
s.speak(20);
}
}

首先来分析下代码

Father s = new Son();: 是向上转型即父类引用指向子类对象,它是对Father的对象的方法的扩充,即Father的对象可访问Son从Father中继承来的和Son复写Father的方法,其它的方法都不能访问,包括Father中的私有成员方法。

s.speak(20);:此处报错,正是因为speak(int age)方法属于子类自己的方法而不是从父类继承而来,在向上转型过程中,父类对象s会遗弃子类中的该方法

总结

继承实际上是存在于面向对象程序中的两个类之间的关系。当一个类拥有另一个类的所有数据和操作时,就称这两个类之间具有继承关系!

多态

多态即同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果

多态分为编译时多态和运行时多态

  1. 编译时多态也称为静态多态,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编译之后会变成两个不同的函数,在运行时谈不上多态。

  2. 运行时多态称作动态多态,它是通过动态绑定来实现的,也就是我们所说的多态性,只有在运行期才知道是调用的那个类的方法。

多态实现形式

基于继承的多态,基于接口的多态,下面分别给出栗子:

  1. 基于继承的多态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Father {
public void say(){
System.out.println("我是父亲");
}
}

class Son extends Father{


@Override
public void say(){
System.out.println("我是儿子");
}
}

class Daughter extends Father{


@Override
public void say(){
System.out.println("我是女儿");
}
}

public class Test{

public static void main(String[] args){
Father f = new Father();
Son s = new Son();
Daughter d = new Daughter();
f.say();
s.say();
d.say();
}
}

执行结果:

1
2
3
我是父亲
我是儿子
我是女儿

通过基于继承来实现多态其实是子类对父类的方法进行了重写,以至于在程序执行时不同的子类对同一个方法会有不同的执行结果

2.基于接口的多态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public interface Animal {
public void say();
}


public class Dog implements Animal {

@Override
public void say() {
System.out.println("狗:汪汪汪");
}
}

public class Cat implements Animal {

@Override
public void say() {
System.out.println("猫:喵喵喵");
}
}
public class Test{

public static void main(String[] args){
Dog dog = new Dog();
Cat cat = new Cat();
dog.say();
cat.say();
}
}

执行结果:

1
2
狗:汪汪汪
猫:喵喵喵

通过实现Animal接口,不同的对象会有不同的实现,在程序执行时同样也会有不一样的执行结果。

多态迷魂阵

继承和多态关系密接,多态是基于继承,继承和多态的理解每个人都各有不同,下面可以看下一个非常有趣的题目,被称为多态迷魂阵

出自博客: https://blog.csdn.net/thinkGhoster/article/details/2307001

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

public class A {
public String show(D obj) {
return ("A and D");
}

public String show(A obj) {
return ("A and A");
}

}

public class B extends A{
public String show(B obj){
return ("B and B");
}

public String show(A obj){
return ("B and A");
}
}

public class C extends B{

}

public class D extends B{

}

public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();

System.out.println("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d));
}
}

执行结果:

System.out.println("1--" + a1.show(b)); A and A
System.out.println("2--" + a1.show(c)); A and A
System.out.println("3--" + a1.show(d)); A and D
System.out.println("4--" + a2.show(b)); B and A
System.out.println("5--" + a2.show(c)); B and A
System.out.println("6--" + a2.show(d)); A and D
System.out.println("7--" + b.show(b)); B and B
System.out.println("8--" + b.show(c)); B and A
System.out.println("9--" + b.show(d)); A and D

参考感谢

面向对象的本质是什么?封装,继承,多态是到底用来做什么的:https://bbs.csdn.net/topics/50019051
多态迷魂阵:https://blog.csdn.net/thinkGhoster/article/details/2307001