面向对象OOP
面向对象是Java中的一种编程思想,这种思想只注重运行的结果而不注重运行的过程,就比如你是一位老板想要达成某个目的,你并不需要自己亲历亲为,而是分配任务给手下的人,同时你也并不在意要达成目的的具体过程,你在意的只是达成目的这个事实
面向对象的三大特征
封装
简而言之就是将相关联的属性封装成一个类,封装之后保证了代码的安全性,降低程序的耦合性,能够对成员变量更精确的控制
继承
继承是将拥有共性的属性和方法进行封装之后在让其他的子类方法继承,一个父类可以拥有很多个子类,但是一个子类则只能有一个父类,继承可以使代码的复用性更高,更简洁,但是也提高了程序的耦合性
多态
多态指一个实体类具有多种形式,我们可以表达所有不同的子类对象都当作父类来看,可以屏蔽不同子类之间的差异,写出通用的代码,统一调用。
类与对象
Java中类就是基本单位,类可以看作是一类事物的抽象,其内封装了对同一事物的描述(变量)和行为(方法),类的具体实现称之为对象,每一个对象都有可能不同。
例子:世界上存在着许多不同的“人”,但是每一个“人”(类)都有基本的五官描述(变量)和一些基本行为,如吃饭睡觉(方法),但是同样的五官描述(变量)具体数值却不一样,比如有的人眼睛大,有的人则眼睛小,同样的行为(方法)有的人睡觉睡8个小时而有的人只需要7小时,将这些描述与行为具体到“某一个人”身上时,我们也可以说这就是“人”的具体实现/对象
对象在内存中的存储
创建的流程
- 首先在栈中开辟一块内存储存变量
- 其次在堆中开辟一块内存储存对象,对象中包含了类中的所有方法与属性
- 刚开始所有的属性都是初始值,然后经过初始化后所以的属性值都变成了你所赋予的
- 对象获得地址交给变量,然后栈中变量获得堆中对象的地址并指向对象且保存地址信息
- 一般来说变量指向的对象都是独一无二的,除非本变量与其他变量共享了地址
构造方法
构造方法是一种特殊的方法,它的方法名与类名相同,修饰符只能使用public,同时并不具有返回值。此方法的具体作用就是帮助对象的初始化,简化操作,同时如果有一些希望在对象创建时就要运行的代码也能写入其中
一个类中可以存在多个构造方法,但是每个构造方法的参数必须不一样,在对象创建的时候根据传参的不同自动调用不同参的构造方法,即为重载。
当一个类中没有自己添加任何构造方法的时候JVM会提供无参的构造方法
当一个类中自己添加了构造方法之后JVM就不会自动提供无参构造方法
程序实例化时会调用构造方法
this的作用
this代表本类对象中的一个引用对象,在构造方法中this(参数)则代表另一个抽象方法,一般不用。例如
class a{
public a(){
}
public a(int b){
this(); //指调用无参构造方法,并且必须放在第一行
}
}
当成员变量与局部变量重名时,this指的是成员变量,因为Java变量遵守就近原则,不用this指代的话无法例如
class a{
String b;
public void setB(String b){
this.b = b; //this.b = 成员变量
}
}
同时还可以使用this.方法名调用本类的方法,但是一般不用
#继承的补充
继承是面向对象的三大特征之一
继承是从已有的类中提取共性之后封装出来一个类,所有的类继承自这个类之后将会自动拥有这个被封装类的所有公开变量与方法,我们称之为子类(派生类),而被封装的类则为父类(超类)。
一个父类可以拥有多个子类,但是一个子类却只能有一个父类。
继承能够有效的提升代码的简洁程度,增加开发的效率,减少开发的成本,但是会增减代码耦合性
特点
- 使用extends关键字
- 单继承
- 继承可以传递(父亲,儿子,孙子)
- 父类的私有方法不参与继承
- 子类继承父类后拥用父类的功能且可以在父类的基础上进行功能的扩展,同时可以重写父类方法
在子类中可以使用super
关键字调用父类的方法与公开的成员变量,但是使用的时候必须置于调用位置的第一行,构造方法中用super()
调用父类的构造方法。
重载(OverLord)与重写(OverRide)
重载:重载可以发生在任何的类中,其规定在一个类中,方法名相同,参数列表不同(可以是个数不同,类型不同)
,比如一个类中可以重载很多不同参数的构造方法,以此来应对各种情况下的对象初始化。
重写:重写发生在父子类中,其规定重写只发生在父子类中,子类重写父类的方法,方法名,返回值,参数列表完全一致,方法体不同。子类的修饰符要大于父类修饰符权限,抛出的异常要小于父类抛出的异常
重写可以对父类中方法进行修改,以应对不同业务下能够以相同的方法解决问题。重写并不意味着修改父类中的代码,只是在子类中另外多写一份。父类中的私有方法不能被重写
static
static:静态的,Java中的关键字,修饰方法为静态方法,修饰变量为静态变量,与final
连用修饰变量时表示此变量为不可更改常量,修饰方法时表示此方法不可重写
特点
- 随着类的加载而加载
- 全局共享只有一份且只加载一次
- 可以被类名点直接调用
- 静态只能调用静态
- static不能与this与super共用,因为static加载时可能还没有对象
静态代码块,构造代码块,局部代码块,构造方法运行时间
顾名思义,构造代码块是写在类中,方法外的代码块,而局部代码块则是写在方法之中,格式如下
class a{
static{
静态代码块
}
{
构造代码块
}
public a(){
{
局部代码块
}
构造方法
}
}
静态代码块:静态代码块随着类加载之后就会马上运行,一般是用来初始化项目
构造代码块作用:提取构造方法中的共性可以简化代码量
局部代码块作用:主要用来规定局部变量的作用范围
运行时间:类加载 -> 静态代码块 -> 对象创建 -> 构造代码块 -> 构造方法 -> 局部代码块
多态的补充
特点
- 多态的使用前提是继承
- 父类的变量指向子类的对象,编译看左边,运行看右边,也称作向上造型,能够点出什么看父类
- 多态的运用提高了程序的扩展性与可维护性
方法与变量的特性
- 成员变量:使用的是父类的
- 成员方法:调用的是父类的方法,但是实现的却是子类的方法体,如果子类未重写则实现父类的方法体
- 静态成员:随着对象而存在,谁掉用就返回谁
final关键字
final:最终的
修饰变量:意味变量不可修改,通常与static
连用,意味常量
修饰方法:方法可以被继承但不可被重写
修饰类: 类不可被继承
异常
异常是用来封装错误信息的对象
父类:Throwable
子类:Exception
,Error
Throwable
是所有异常与错误的父类,Exception(异常)
是代码的不规范或者其他原因所导致的程序终止所抛出来的一个封装了错误信息的对象,Excpetion
是可以被捕获与解决的。Error(错误)
并不是人为可以控制的一种错误,它的问题主要发生在硬件方面而非软件的错误,这种错误一般无法通过更改代码来解决,只能解决硬件方面的问题。
Exception
也被称为受检异常
,也就是说是可以在编译期被编译器检测出来的异常,这类异常不处理将无法运行程序
RuntimeException
也称为非受检异常/运行时异常
,它虽然是Exception
的子类,但是它是无法被编译器检测出来的,它将会在程序运行时抛出导致程序的强制终止。
异常的处理
异常的处理方式有两种
抛出:在方法的的后面添加throws
关键字与想要抛出的异常类型,当调用此方法出现异常时,异常会自动抛给调用者,如果调用者选择继续抛出或者未作处理则会一路抛到main
方法外,导致程序的强制终止
捕获:在可能抛出异常的代码块前后添加try..catch
关键字能够捕获异常,在try
中捕获异常将会不再执行抛出异常代码之下的所有代码,会直接跳到catch
中进行异常的处理。
finally
关键字意味着该代码块内的内容无论有没有出现异常都会执行。
权限修饰符
public:公共的,修饰的变量方法能够在任意地方被访问
default: 变量与方法的默认修饰符,写了报错,不写默认存在,能够在类,同包中访问
protected: 受保护的,被修饰的变量与方法能够在本类,同包,与同包中的子类中进行访问
private:私有的,用于修饰成员变量与方法,Java变量的封装主要依赖于此修饰符,当用此修饰符修饰类中变量时,对外来说就此变量会变得不可见,想要对变量进行查看与修改则需要依赖自己所写get/set方法。
在单例模式下,修饰构造方法后,对象将会变得无法实例化,只有依靠对外提供的接口来进行实例化
###抽象类与抽象方法
特点
- abstract可以修饰方法与类
- 修饰类则为抽象类,修饰方法则是抽象方法,抽象方法没有方法体,具体逻辑交给子类重写
- 抽象类无法进行实例化,必须要继承它才具有意义。
- 抽象类可以含有普通方法,有抽象方法的类一定是抽象类
- 任何类都继承了Object类,所以抽象类也存在无参构造方法
- 子类继承抽象类要么重写所有抽象方法,要么当作抽象子类继续继承给其他子类
- 抽象类中可以有变量,也可以有常量
接口
接口(Interface)是Java提供的另一种抽象的类型,接口之间能够实现多继承,解决了Java类之间的单继承问题吗,提高了代码的可扩展性,可维护性
特点
- interface修饰
- 接口中所有方法皆为抽象方法,所有变量皆为常量
- 接口之间可以多继承,一个类也能实现(implements)多个接口
- 接口突破了Java单继承的局限性
- 提高了程序的可扩展性,可维护性,降低了耦合性
- 对外暴露规则,是一套开发规范
- 接口没有构造方法
接口与抽象类区别
相同点
都是抽象的,都不能进行实例化
不同点
- 抽象类可以存在普通方法,而接口不存在普通方法
- 抽象类可以存在普通变量,而接口只有常量
- 抽象类有构造方法,而接口没有
- 抽象类只能单继承,而接口可以被类多实现
- 抽象类中可以手动给方法添加访问权限,而抽象类中的方法全是公开方法
补充知识:值传递与引用传递
值传递:发生在基本类型之中,意味着将实际的参数复制一份传递给其他变量,变量之中具体保存是值
方法
2. 抽象类可以存在普通变量,而接口只有常量
3. 抽象类有构造方法,而接口没有
4. 抽象类只能单继承,而接口可以被类多实现
5. 抽象类中可以手动给方法添加访问权限,而抽象类中的方法全是公开方法
补充知识:值传递与引用传递
值传递:发生在基本类型之中,意味着将实际的参数复制一份传递给其他变量,变量之中具体保存是值
引用传递:发生在引用类型之中,引用传递传递的是保存对象的地址,即传递与接受的两个变量都会指向同一个对象