面向对象,static关键字,继承以及多态的理解及一些细节。

static关键字可以修饰成员变量,成员方法

读成静态成员变量,静态方法
特点:1.被static修饰的成员被该类的所有对象所共享
2.被static修饰的成员,会随着该类的字节码文件的加载而加载,优先于对象存在(对象是要在字节码文件加载完后才能创建的,而静态成员是字节码文件只要加载完就存在的,不用另外进行创建,所以会优先于对象存在),所以静态成员方法中不能含有非静-!
态成员,也不能有this关键字(this关键字代表的是当前对象的引用,而静态方法是在对象还没创建就能使用的,所以当静态方法使用的时候可能对象还没创建出来,因此是不能这样定义的。),但是非静态方法中是可以使用静态成员和方法的。(因为非静态方法是肯定要在对象创建完后才能使用的,而对象的创建也是肯定要在字节码文件加载完成后才能创建的,而字节码文件加载完成就代表着静态成员已经初始化完成。所以当能使用非静态成员方法的时候,也是肯定能使用静态成员变量和方法的。所以是能在非静态成员方法里面调用静态成员的。)
3.静态成员可以通过(类名.)的方式进行调用,也可以通过(对象名.)调用,但是推荐第一种。

继承

什么是继承:
是在已有类的基础上派生出新的类,在原有的功能上进行扩展,新的类能吸收原有类的属性以及方法,并扩展新的功能。
继承能解决什么问题:
继承能解决代码重复性的问题,能提高代码的复用性。能使得代码的维护更加方便。
在创建一个子类的对象时,是必须要先初始化父类的,因为如果在子类中调用了父类的成员而父类有没有初始化好的话,就会出问题了,而这里的初始化又可以说一段了,这里可以引出一个技术点super();在每一个子类的构造方法中的第一行都有super();这一行代码,这代表着调用父类的构造方法。而调用父类的构造方法就会初始化父类。所以初始化子类前都会初始化好父类。如果父类没有空参构造方法供super()调用,那么,子类中的构造方法则会报错。那么这里的初始化又可以拿出来说一下了,初始化的时候会先把所有的成员变量都初始化好,最后在执行构造方法中的代码(构造方法中有super()关键字,会先执行super()关键字。)
子类继承父类的内存图理解。在这里插入图片描述
在创建子类对象的时候,这里子类对象的堆内存中会专门存在一个super父类的存储空间。这里的存储空间会专门存储父类中的不可以直接访问的私有成员,但是可以通过父类提供的其他非私有方法进行访问,父类中其他非私有成员会直接在子类的堆内存中存在,可以直接访问。(注意:继承中父类的私有成员,并不是继承不到,而是不能直接访问,他还是存在于子类的堆内存中的。)(子类可以直接访问父类中的非私有成员,不能直接访问私有成员。)
继承带来的好处与弊端:
好处:提高了代码的复用性,可维护性(如果方法中的代码要修改,修改一处即可。)但是对于可维护性来说,既是好处也是弊端,因为你只要修改一处的原因是因为类和类的关系非常强,所以在这里你的耦合性也增强了。
特点:
java只支持单继承,不支持多继承,但是可以多层继承,也就是可以有孙子,爸爸,爷爷,。。。。多重关系。
继承中成员变量的访问特点:(就近原则)
在子类方法中访问一个变量,首先在子类方法内部寻找,然后在子类成员变量中寻找,然后在父类成员变量中寻找,当然如果有父类的父类也会依次寻找上去,如果都没找到那么就会报错(方法也是同理。)

this,super关键字的使用
this代表本类对象的引用。(括号中可以传入参数。)
1。(this.成员变量),代表访问本类成员变量,如果本类成员变量中没有就会去父类成员变量中去寻找,如果没找到则会报错。
2。(this.成员方法()),代表访问本类成员方法,如果本类成员方法中没有就会去父类成员变量中去寻找,如果没找到则会报错。
3。(this())代表访问本类的构造方法,这里不会去父类中寻找。
super代表父类对象的引用。
1。(super.成员变量),代表访问父类成员变量
2。(super.成员方法()),代表访问父类成员方法
3。(super())代表访问父类类的构造方法
注意:this()和super()必须在构造方法中的第一行有效语句,否则会编译报错,这就是为什么this和super关键字不能同时存在的原因。

方法的重写

方法的重写只会存在于类的继承与接口的实现中。
方法的重写的规范,权限修饰符,重写后方法的权限修饰符必须大于等于重写前的权限修饰符。
其余返回值,方法名参数列表必须保持一致。
这里提到一个注解
Override注解
用来检测当前的方法,是否是重写的方法,起到【校验】的作用。
注意事项,私有成员方法不能重写,因为父类私有成员是访问不到的。
在这里插入图片描述

静态方法也是不能重写的,但是你在子类中可以定义一个一样的方法,现象上是重写了方法,但是其是并没有重写该方法的。

抽象类

个人理解,抽象类是对继承中的一种升级,因为有时,在继承中,父类的方法有时并不能直接给出完整的业务逻辑代码,只有在子类中才能给出特有的逻辑代码,所以这时的抽象类的作用就出来了,抽象类中可以定义抽象方法,(抽象方法:指的是,在方法声明中给出abstract关键字,没有方法体的方法。例:public abstract void print();)普通类继承抽象类时要重写抽象方法。(注意:abstract和static不能同时存在于一个方法中。)
抽象类和普通类的区别在于,抽象类可以定义抽象方法,抽象类不可以实例化创建对象。抽象类在定义时需要加上abstract关键字(public abstract class A{})。其他基本一样。注意:一个抽象类中可以没有抽象方法,但有抽象方法的类一定要是一个抽象类。
(注意:其存在构造方法,但其不能创建对象,其构造方法是用来初始化该类的。)

模板设计模式

首先介绍一下设计模式:是一套被反复使用,多人知晓的,经过分类编目的,代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
模板设计模式:
理解:将已经确定好的业务逻辑给定好,将没有确定的业务逻辑定义为一个抽象方法,让子类去实现这个抽象方法并给出自己特有的业务逻辑。之所以称为模板设计模式,就是在套用一个给定好的模板,已经确定好的业务逻辑加上没有确定好的业务逻辑就是一个模板。(没有确定好的业务逻辑,指的就是要用户实现自己功能的那一块的代码。)

优势:我们只需要关注自己实现的功能即可,也就是那个抽象方法。

final关键字

final:中文意思,代表最终的意思。
final可以修饰类,修饰方法,修饰变量
修饰类代表该类不能被继承,但是其可以有父类,修饰方法代表该方法不能被重写,修饰变量代表该方法是一个常量,这里涉及到,一个知识点,
字面值常量,自定义常量。
字面值常量:例如那个字符串常量,指的是那个被双引号引起来的常量,字面值,顾名思义,就是那个值。
自定义常量:指的是用final修饰的变量的那个变量名,用final修饰的变量名只能被赋值一次,所以称为常量。
如果final修饰的是基本类型,那么不能改变的是值。如果修饰的是引用类型,那么不能改变的是地址值,但是地址值里面的内容还是可以改变的。
(注意:如果定义了一个最终的成员变量,那么在构造方法执行完之前就要对其初始化好,建议在声明该变量的时候就对其赋值。但如果是局部变量可以不对其进行初始化。)
在这里插入图片描述
在这里插入图片描述

代码块

代码块分为三种。
1.局部代码块:定义位置:定义在方法的内部。当其执行时,会进入栈内存,当其执行完后会弹栈消失,代码块中的变量在代码块外部是访问不到的。但代码块内部能访问到外部的变量。
2.构造代码块:定义在类中方法外,会随着构造方法的执行而执行。
3.静态代码块:定义在类中方法外,使用static关键字进行修饰,会随着类的加载而加载,只会执行一次,所以一般用来初始化一些配置文件。

接口

接口:
理解:用来定义规则,所有要想使用该接口都必须要实现该接口所定义的规则。
用来做功能的扩展(这里可以深入了解一下,其实定义接口的原则并没有一个实际的概念,非常的抽象,就像mysql的数据库驱动,他是基于javaJDBC接口实现的一个具体驱动jar包,javaJDBC提供了一套规则,数据库厂商可以根据这套规则去实现自己的数据库驱动例如市面上都很火的几种数据库驱动,MySQL,oracle,sqlServer,等等,这些都是根据javaJDBC的接口来实现的自己的具体的驱动jar包,所以,我自己总结了一下设计接口的原则,就是,定规则,拓展性要强,因为我们不知道未来会是怎样发展的所以我们定义规则,我们不把具体的业务逻辑给写死,留给未来一些发展空间,让其在遵守我得规则下,进行扩展,其实现实生活中这种例子很多,例如,笔记本电脑所定义的USB接口,笔记本定义了一个USB接口的规则,你只要符合我这个规则。你可以进行随意的扩展,鼠标,键盘,外接硬盘,U盘,等等,都是在遵守USB接口的基础上对另外的功能进行扩展。其实我们以后自己写的代码,自我感觉是没有遵守这个规则的,我们是在为了使用接口而定义接口,可能也是因为我们做的开发并不是企业级的项目吧。)
规则:就是接口中的抽象方法,要想使用我这个接口就必须实现我的抽象方法。
拓展:就是对抽象方法可以随意进行重写,可以写自己特殊的业务逻辑。

特性
1.接口中可以定义成员变量,但其系统会默认为其加上3个关键字。
public,static,final
成员方法:系统默认会默认增加两个关键字,public,abstract
例如:public abstract void print();//我们平时写代码可能就只会写void print();系统会默认为其加上public abstract 关键字

JDK8新特性:可以在接口中定义带有方法体的默认方法
例如:public default void print(){
//写业务代码逻辑
}
(默认方法也可被重写,但重写时要去掉default关键字)
(和类一样,接口中的静态方法只能调用静态方法,不能调用其他方法。
普通方法能调用静态方法,也能调用普通方法。)
(还有一点,如果自己没给定权限修饰符,系统会自动默认的加上public关键字)
该新特性加上就是为了以后对接口的升级时,不用在对子类的代码进行修改,因为如果直接在接口中写抽象方法的话,那么所有实现了该接口的类,都要重写该抽象方法,否则就会报错,而如果写默认方法的话就不用在子类中再去重写方法了,并且也可以在实现类中进行调用。

8版本中还有一个新特性加入了静态方法也是可以自带方法体的
public static void print(){
//写业务代码逻辑
}
该静态方法只能通过(接口。)的方式去调用,其他的调用方式都不行。
(注意:其还存在一个方法冲突的问题,因其存在多继承,就是一个接口可以继承多个继承,一个类可以实现多个继承,如果是一个接口多继承其他接口产生的方法冲突,如果是抽象方法冲突,那么直接忽略掉一个方法,因为其都是没有实现业务代码逻辑。如果是默认方法冲突,那么需要重写该默认方法,一个类实现多个接口时产生的冲突也是如此,只有可能是默认方法冲突,直接重写该默认方法即可)
9版本中新增了一个私有方法,该方法的定义和普通私有方法的定义是一样的,这里新特性产生的原因是,当两个默认方法或静态方法产生了相同的业务代码逻辑的时候,程序必然就会考虑就这两段共性代码抽取成同一个方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java 9增加私有方法的必然性。

多态

多态是什么:
同一事物在不同时间展示的不同形态,叫做多态。
多态的前提:
有继承或实现,方法的重写,父类引用指向子类对象,的情况下才存在多态。
在这里插入图片描述
上图中父类引用调用同一个方法,程序却打印出了不同的结果。这就是最好的多态的体现,根据传入的子类对象不同,而运行结果不同。(因为是,同一事物在不同时刻展现的不同形态嘛,在Animal是dog的时候打印出狗吃东西,在cat的时候打印出猫吃东西。)
多态中成员的访问特点:
1.成员变量,
编译和执行都是看的父类,不会去子类中查找,如果父类中没有该变量,直接报错。
2.成员方法,
编译看的是父类,如果父类中没有该方法那么,编译的时候就会报错,但是运行的时候调用的是子类中的方法。(如果子类没有该方法,而该方法又不是抽象方法的话,会执行父类中的方法。)这里的特点也诞生出了多态的一个弊端,就是使用不了子类中特有的方法。因为如果父类中没有该子类中特有的方法,而又去强行调用子类中特有的方法,就会直接编译报错。
但是这里也有一个解决方案,
向下转型,将父类应用强转为子类类型
格式:
子类类型 变量名=(子类类型)父类引用;
例:Cat c=(Cat) animal;
把父类引用向下转型为子类类型引用,子类类型就可以调用子类中特有的方法了,但是这里也有一个风险,就是如果父类引用的对象类型不是所要转换子类类型的话,就会报出ClasscastException异常(例如,如果父类引用,引用的是一个Dog类型的对象,但是你要给他向下转型为一只猫类型的话,就肯定不行。)
这里衍生出一个关键字,instance ,该关键字用来判断父类引用的对象类型是不是子类的类型,返回一个boolean值。
在这里插入图片描述
而和向下转型相对的就是向上转型,
向上转型就是父类引用指向子类对象,
这里的两个专有名词是用来形容引用数据类型。
(这里也可以提一下强制类型转换,和自动类型提升,强制类型转换,
是将范围大的数据类型转换为范围小的数据类型,格式:
在这里插入图片描述
可能会产生数据丢失,自动类型提升,是在程序运行的时候自动做的。但是这两个专有名词是专门用来形容基本数据类型的。)
而好处就是多态的特性了,在定义方法的时候可以使用父类类型做为参数,再调用方法的时候可以使用子类对象作为实参进行传递,从而执行不同子类中不同的重写方法执行不同的业务逻辑。从而提高程序的扩展性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值