Java中的封装,继承和多态(详解)

封装

所谓的封装就是把类的属性和方法使用private修饰,不允许类的调用者直接访问,我们定义如下一个类,可以看到所有的成员变量和成员方法都使用private修饰了,我们现在来使用一下这个类。
在这里插入图片描述
当我们使用的时候编译器给出了下面这样的报错。在这里插入图片描述
告诉我们说是private访问控制,那么这是什么意思呢?我们来看看另外一张图,那么这张图代表这什么呢?在看这张图之前,我们先来看看四者都提到的包,那么包又是什么呢,包可以简单理解为一个文件夹,把类放到放到包里面,也就相当于是专门的文件夹里面,这不是我们说的重点,知道就行,类都知道吧,不知道的先去看看博主这篇博客类和对象再回来继续往下。
ps:稍微记一下这张图中的内容。
在这里插入图片描述
在这里插入图片描述
有了上面的基础我们现在再来看private,他的使用范围只有 同一个包中的同一个类中使用(这个范围也就是他的权限),我们就记住只能在我们定义的那个类中使用就好了,别问为什么,因为这就是语法,记住就好了,记准确了是当前类中,不能外部引用,否则就会出现上面那样的报错。既然不能直接从外部引用,那么类的调用者总得有个办法使用吧,不然实现这个类干嘛,这个时候就是我们在设计类的时候要提供的公开的方法了,那么上述的代码应该写成如下形式。
在这里插入图片描述

在这里插入图片描述
ps:这里重写了toString方法才会是下面的输出形式。
上面就是调用了,那么有的读者可能就会问了,那你的eat方法还是private的呀,我还是不能调用啊,这里我解释一下,这是因为我是为了演示private的作用而在eat方法前面加的private,运行时我将它注释掉了,至于实际上像eat这样需要被类的调用者直接使用的方法,肯定是不能使用private修饰的,至于用什么访问权限修饰这就是类的设计者根据日后业务的需要而决定了。
封装的第一个作用就是为了不直接被外部使用,提高代码的安全性,第二个作用就是降低类的使用者的学习成本,不需要知道类的实现,只需要学会调用就好了,封装差不多就介绍完了,接下来聊聊继承。

继承

所谓继承本质就是实现代码的复用,防止重复的代码多次书写,当一个类继承一个类的时候,该类中就会拥有另外一个类中的所有代码,举个例子看下面代码
在这里插入图片描述
可以看到继承的语法形式是class 子类名 extends 父类名,继承类就是子类,也叫派生类,被继承的类称为父类,基类或者超类(名字一般不做区分,均可使用),语法形式很简单,我们来聊聊其中的细节,首先Java是单继承的, 一个子类只能有一个父类,但是一个子类可以当作另外一个类的父类,即可以B继承A,然后C继承B,代码如下,那么B会拥有A中的代码,C会拥有A、B的代码。
在这里插入图片描述
下面讲的普通类继承知识都是基于父类是公开的并单独位于一个.java文件的。
我们定义一个这样的Animal类当作父类:
在这里插入图片描述
当访问使用private修饰的属性时就会报错,这个就是上面封装的知识了,只能在定义的类中使用。
在这里插入图片描述
当去掉private不加任何修饰符时为包访问权限(对应上面的default范围,至于default关键字的使用在接口当中会提到),当前包底下的类才能使用Animal中的属性。
在这里插入图片描述
在这里插入图片描述
当使用protected修饰时,是可以在子类中调用的,那么下面为什么会报错呢,那是因为调用的方式不对,这里我们需要改变访问方式并使用到super关键字。
在这里插入图片描述
在这里插入图片描述
改为如下调用,在子类中调用,并使用super关键字,而不是通过实例化对像调用,上面那张图除了提到包还提到了类,小伙伴们注意到了吗?不记得的小伙伴们就往上翻再看看那张图吧。
在这里插入图片描述
至于public没啥好说的,哪都能用。
上面呢介绍了继承普通类的知识,现在我们来看看不太正常的类,抽象类,抽象类是指被abstract修饰,包含抽象方法的类,如下就是一个抽象类,首先是类名前面添加了abstract关键字,其次是其中包含了一个抽象方法,什么是抽象方法,就是没有被具体实现的方法,如下图的work方法,没有方法体,并被abstract修饰,不加的话会报错,被abstract修饰的类中可以没有抽象方法,这是语法允许的(jdk1.8测出来的),但是建议同步使用,要么既有abstract修饰类又有abstract方法,要么都没有,不然使用了abstract修饰类又不加abstract方法这不是闹吗,除非你不想这个类直接被实例化,注意一点,abstract修饰的类不能直接被实例化,需要被继承之后通过子类调用父类的构造方法,对从父类继承过来的字段进行初始化,注意这些继承过来的字段和方法都到了子类中了,但是子类能不能使用和如何使用就和给的权限(使用了什么访问修饰符限定)相关了,并没有实例化产生一个父类对象,有些地方说会实例化一个父类对象这是不对的,说一个极端的说法,父类为抽象类你能实例化吗?
在这里插入图片描述
在这里插入图片描述
当一个普通类继承一个抽象类的时候需要重写抽象类的所有抽象方法,如果不想重写的话就需要声明为抽象类,看下面代码
在这里插入图片描述
在这里插入图片描述
继承主要是为了代码的复用,减少代码的重复书写和为多态打一个基础,接下来我们聊聊多态

多态

多态是一种思想,是同一份代码,不同的传参(子类)调用会产生不同的效果,绝对不是写死的代码
多态是建立在继承机制上的一种机制,想要了解多态就必须知道向上转型,那么什么是向上转型呢,所谓的向上转型就是使用父类对象的引用,引用子类对象看下面代码
在这里插入图片描述
在这里插入图片描述
Teacher是People的一个子类,使用People引用引用一个Teacher对象,向上转型是自动发生的,不需要进行强制类型转换,发生向上转型一般有三种情况
1.像上面代码一样,让父类引用直接引用子类对象时。
2.子类作为函数调用时的实参,使用父类形参接收时。
3.子类作为父类返回值函数的返回值时。
总的说就是父类引用引用了子类对象
在这里插入图片描述
红色的框表示第二种,橘黄色的框表示第三种
ps:不难理解吧QAQ
与向上转型对应的还有向下转型,就是将父类对象赋值给子类引用,一般很少用的,就简单的提一下吧,因为他发生条件比较严格,首先是不能直接强制类型转换,看下面代码(已经将People类变成了类)
在这里插入图片描述
其次是需要父类引用引用子类的对象(发生过向上转型),最后需要强制转换为对应的子类对象,像下面这样
在这里插入图片描述
ps:这东西用起来挺奇怪的,不太建议使用
到这里相信你应该知道什么叫做向上转型了,但是这还不足以接触多态,我们需要先来聊聊另外一个知识点,动态绑定,所谓动态绑定也叫运行时绑定,我们先来看看代码
在这里插入图片描述

在这里插入图片描述
首先可以看到三个输出,第一个输出睡觉,第三个输出教书没问题吧,问题就出在第二个上面,我明明调用的是people的work方法,为什么输出的不是睡觉,而是教书呢?这就是发生了动态绑定,所谓动态绑定就是使用父类引用引用子类对象然后(向上转型)去调用父类和子类相同的方法(返回值(构成父子类关系也可以,也就是协变类型),方法名,形参列表完全相同)换句话说也就是说在子类中重写了父类的方法,这样的重写需要注意一些点,那就是子类重写的方法的访问权限必须不小于父类的方法的权限也就是说父类为public子类就必须为public因为public是最大的权限,权限对应上图的 的个数√越多权限越大,静态方法不能重写,被final修饰的方法(密封方法)不能重写。
ps:与动态绑定对应的还有静态绑定,这里就不多说了…
好了,知道了向上转型和动态绑定就可以了解多态了,看代码
在这里插入图片描述
是不是觉得很神奇,明明是指向了同一份代码却打印了不同的结果,这就是多态,我不管你怎么实现的方法,只要你有这个方法我就能帮你调用,并且这里如果是子类对象会发生向上转型,进而发生动态绑定,形成多态,上面是通过继承来实现的多态,接下来我们再来讲一个东西实现多态,接口

接口

那么接口是什么呢,接口也可以想象成一个类,但是它既然单独出现,肯定说明它和类有有所不同,首先接口由interface关键字定义,并且其中的所有方法都默认为public abstract的,所有字段都默认为public static final的,下面几种定义方式并无区别,在这里插入图片描述
然后类似与继承,接口可以通过implements被实现,实现也很简单,和继承抽象类一样重写所有的抽象方法即可,同样接口不能被直接实例化。
在这里插入图片描述
有了上面的了解,我们来用接口实现多态,看下面代码,也和类实现多态没什么很大区别,也类似与发生了向上转型和动态绑定,实现接口和继承类的一个很大区别就是一个类只能继承一个类,但是一个类可以实现多个接口
在这里插入图片描述
在这里插入图片描述
其中接口也可以扩展接口,看下面代码
在这里插入图片描述
从jdk1.8开始接口中可以包含默认方法了需要使用default关键字修饰,和类的成员方法一样,看下面代码,到这里接口就差不多聊完了,小结一下
在这里插入图片描述

一些建议和小结

1.建议字段的访问权限能给小绝不给大,能使用private修饰的字段一定要用private,提高安全性。
2.继承的层次不要太深,建议最多继承三层,使用final修饰可以让类无法被继承。
3.抽象类的出现就是为了继承之后重写发生动态绑定。
4.能使用接口就不要使用抽象类,因为类只能单继承,但是接口可以“多继承”,更加的灵活。
5.多态的核心都是让调用者不必关注对象的具体类型. 这是降低用户使用成本的一种重要方式。
6.抽象类和接口的核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 接口中只能包含静态常量,子类必须重写所有的抽象方法。
7.接口中的方法和字段定义都只写必要部分,尽量简洁像博主上面一样

写在最后的话

以上就是博主这段时间学习的主要内容了,也查了不少资料,限于博主水平有限,文章难免有说错或表述不清的地方,欢迎小伙伴们在评论区或私信博主指出,最后希望本篇博客能对小伙伴们有所帮助,好了本篇博客到此就结束了,我们下篇博客见。

  • 159
    点赞
  • 511
    收藏
    觉得还不错? 一键收藏
  • 73
    评论
【完整课程列表】 资源汇总下载地址:https://download.csdn.net/download/qq_27595745/55418618 Java SE编程入门教程 collection与collections(共7页).pptx Java SE编程入门教程 java GC(共6页).pptx Java SE编程入门教程 java instanceof(共3页).pptx Java SE编程入门教程 java IO(共28页).pptx Java SE编程入门教程 java Math(共11页).pptx Java SE编程入门教程 java object(共9页).pptx Java SE编程入门教程 java static final(共24页).pptx Java SE编程入门教程 java this和super(共10页).pptx Java SE编程入门教程 java 常用API(共22页).pptx Java SE编程入门教程 javaGUI编程快速入门(1)(共82页).pptx Java SE编程入门教程 java包装器(共9页).pptx Java SE编程入门教程 java反射机制(共16页).pptx Java SE编程入门教程 java泛型(共11页).pptx Java SE编程入门教程 java封装继承多态(共56页).pptx Java SE编程入门教程 java集合(共38页).pptx Java SE编程入门教程 java接口(共21页).pptx Java SE编程入门教程 java类和对象方法以及包的使用(共56页).pptx Java SE编程入门教程 java类和对象方法以及包的使用(共62页).pptx Java SE编程入门教程 java判断循环(共79页).ppt Java SE编程入门教程 java入门以及变量debug(共63页).pptx Java SE编程入门教程 java设计模式(共17页).pptx Java SE编程入门教程 java数组(共33页).pptx Java SE编程入门教程 java网络编程(共29页).pptx Java SE编程入门教程 java线程(共61页).pptx Java SE编程入门教程 java序列化(共14页).pptx Java SE编程入门教程 java异常(共57页).pptx Java SE编程入门教程 java正则(共8页).pptx Java SE编程入门教程 properties(共3页).pptx Java SE编程入门教程 String字符串(共27页).pptx Java 位运算.docx java正则表达式例子大全 共10页.doc JAVA正则表达式实例教程 共17页.docx JAVA正则表达式实例教程 共17页.pdf 递归算法.docx 堆和栈.wps

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 73
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值