面向对象
面向对象
1.定义:
____ 所谓面向对象就是把现实中的事务都抽象成程序设计中的对象,基本思想就是一切皆对象,是一种"自上而下"的设计语言,先设计组件,在完成拼接。面向对象是用于大型复杂系统,因为它方便复用,易维护,易扩展,主要是由于面向对象的三大主要特性 封装、继承、多态,所有才可以设计出低耦合的系统,使系统更加灵活,易于维护。封装是把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的对象中,还有就是隐藏对象的属性和实现细节,仅对外提供公共的访问方式,将变量隔离,提高了代码的安全性,一个良好的封装能够减少耦合,实现“高内聚,低耦合”。继承就是子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法,或是子类从父类继承方法,使子类具有父类相同的行为。提高的代码的复用性,使类与类之间产生了关系,是多态的前提。多态就是父类引用指向子类对象或接口引用指向实现类。多态的表现形式重要表现为两个方面方法的多态和对象的多态。方法的多态就是重载跟重写,对象的多态就是向上造型跟向下造型 。
2.优势:
适用于大型复杂系统,方便复用,易维护,易复用,易扩展,由于面向对象有封装、继承、多态的特性。可以设计出低耦合的系统,是系统更加灵活、更加易于维护。
3.劣势:
比较抽象,性能较比面向过程低。
4.三大主要特征:
1、封装性:
在面向对象技术的相关原理以及程序语言中,封装的最基本单位是对象。封装是把对象的属性和行为看成一个密不可分的整体,将两者封装到一个对象中,而使得代码结构实现“高内聚、低耦合”的“最佳状态”。封装还做到隐藏对象的属性和实现细节,仅对外提供公共的访问方式将变化隔离,便于使用提高代码的复用性与安全性。
2、继承性:
继承是面向对象编程技术的基石,因为它允许创建等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象具有与父类相同的实例域和方法,或者子类从父类继承方法是的子类具有父类相同的行为。
3、多态性:
从宏观的角度来讲,多态性是指在面向对象技术中,当不同的多个对象同时接收到同一个完全相同的消息之后,所表现出来的动作是各不相同的,具有多种形态;从微观的角度来讲,多态性是指在一组对象的一个类中,面向对象技术可以使用相同的调用方式来对相同的函数名进行调用,即便这若干个具有相同函数名的函数所表示的函数是不同的。
-.1.this与super
- _this:指代的是当前对象,哪个对象调用方法他指的就是哪个对象,this只能用在方法中,方法中访问成员变量之前默认有一个this。
- _super:可以理解为是指向自己的父类对象的一个指针,而这个父类指的是离自己最近的一个父类。
- 相同点: 都需放在构造方法的第一行。都指的是对象,所以均不可以在static环境下使用。
- 不同点: this是一个指向本对象的指针。 super是一个java关键字。
-.2.final关键字
- 修饰的类:不可以被继承
- 修饰的成员变量:变量为常量不可以改变
- 修饰的成员方法:不能被重写
- 修饰局部变量:-基本类型:值不能改变; -引用类型:地址值不能改变
- 让子类的重写权限变得可控,如果父类的某个方法不让子类重写, 可以用final修饰变成最终方法。
-.3.static关键字
- 修饰成员变量:静态变量 (static不可以修饰局部变量。)
静态变量与非静态变量区别:
静态变量被所有对象说共存,在内存中只存在一个副本,它当且仅当类初次加载时会被初始化。
非静态变量是对象说拥有的,在创建对象时被初始化,存在多个副本,各个副本互不影响。 - 修饰成员方法:静态方法
由于静态方法不依赖与任何对象就可以访问,因此,对于静态方法来说是没有this的。因为它不依赖与任何对象,既然没有对象,就谈不上this了。由于这个特征,在静态方法中不能访问类的非静态变量和非静态方法,因为非静态变量和非静态方法都必须依赖于具体的对象才能被调用。 - 修饰代码块:静态代码块
静态代码块主要就是用来优化程序性能。静态代码块可以放置于类的任何地方,可以有多个,在类初次加载时,会按照静态代码块的顺序执行每个静态代码块,并且只会执行一次。
–wp:注意事项.
–1.在静态方法中,不能出现this、super
–2.静态方法只能访问静态成员
–3.工具类中的成员一般来说是静态成员,目的是节约内存空间。
–4.在外部调用静态方法时,可以直接使用“类名.方法名”的方式,也可以使用“对象名.方法名”的方式但不建议。
–5.特点.随类加载而加载,优先于对象存在,全局唯一,全局共享。
-4.成员变量和静态变量的区别
- 所属不用:成员变量-属于对象(实例变量) ; 静态变量-属于类(类变量)
- 内存位置:成员变量-存在 堆 ; 静态变量-存在 方法区
- 出现时间:成员变量-随对象加载 ; 静态变量-。随类加载而加载,消亡而消亡
- 调用方式:成员变量-只能通过对象 ; 静态变量-调用通过类名.点、对象调用(不建议)
-5.成员变量和局部变量的区别
- 类中位置:成员变量-在类中方法外面 ; 局部变量-在类中方法、代码块、参数列表中
- 内存位置:成员变量-存在 堆中 ; 局部变量-存在 栈中
- 生命周期:成员变量-随对象加载 ; 局部变量-随方法的调用、代码块的执行
- 初 始 值 :成员变量-有默认值 ; 局部变量-没有默认值,使用前需要赋值
-6.重载和重写
- 重载:发生在同一个类中,方法名相同,参数列表不同,方法体不同。“编译期”
- 重写:发生在父子类中,方法名相同,参数列表相同,方法体不同。“运行期”
两同(方法名、参数列表).两小(返回值类型、异常).一大 (访问权限)
-7抽象类和抽象方法
7.1.特点
- abstract 不能与 private、final、static、synchronized、native关键字共存。(abstract 没有方法体,没有实现)
- 抽象类不可以实例化。仍然会提供构造方法,因为方便子类new。
- 抽象类不一定有抽象方法,但有抽象方法的类一定是抽象类。
- 抽象类里可以都是抽象方法,要求子类重写所有的抽象方法,否则就是一个抽象的子类。
-8.接口
Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现。
8.1. 特点
- 接口不能实例化对象
- 接口中没有构造方法
- 接口中所有的方法必须是抽象方法
- 接口支持多继承
- 接口中没有成员变量,只有为变量自动拼接 public static final 的常量。
- 接口里的方法可以有抽象方法和用 static、default修饰的普通方法。
- 实现类实现接口后,需要重写所有的抽象方法,否则就是一个抽象的实现类。
8.2. 抽象类和接口的区别
–相同点
- 都可以出现抽象方法
- 都不能被实例化
- 都需要子类重写抽象方法
- 接口 和 抽象类 体现了继承结构里的 抽象层
- 问题: 抽象层的表现可以是接口?也可以是抽象类?–到底设计成谁?
答案: 看需不需要提供方法体,
如果都是抽象方法,那就直接设计成接口,还可以多继承多实现更灵活
如果有普通方法,那就还是设计成抽象类吧,坏处是只能单继承
–不同点
- 抽象类里有构造方法,用来给子类创建对象.接口里没有构造方法.
- 抽象类里有变量,但是接口里,只有常量,会为简写的常量自动拼接
public static final - 抽象类里有普通方法,但是接口里,都是抽象方法(除了jdk1.8)
- 接口里的抽象可以简写,会为简写的抽象方法自动拼接public abstract
- 抽象类只能是和子类之间发生单根继承关系
- 接口和实现类之间是实现 关系,而且可以 多实现
- 接口和接口 之间是继承 关系,而且可以 多继承
- 接口 是为了突破java单继承的局限性来的
-9.构造方法Constructor / 构造器
触发的时间节点:构造方法摆在那儿不会主动执行,需要new来触发 构造方法可以重载,为了方便各种new,体现程序的灵活性 构造方法在创建对象时,会自动执行
-10.代码块
1.创建对象时:本来是只会触发构造方法,但是,如果有构造代码块,就会触发构造代码块再执行构造方法。
2.调用方法时:顺序执行方法里的代码,如果有局部代码块也就一起执行。
3.执行顺序:new时-构造代码块>构造方法,调用方法时–局部代码块,类加载时–执行静态代码块。
4.构造代码块–用来提取构造方法的共性–new时才触发
5.局部代码块–用来控制变量的作用范围–调用方法时才触发
6.静态代码块–用来初始化项目-位置在成员位置 static{…}
-11.内部类、匿名内部类
内部类定义: 把一个类定义在某个类中的,这个类就被称为内部类
特点:
–内部类可以直接访问外部类中的成员,包括私有成员
–外部类要访问内部类的成员,必须要建立内部类的对象
–在成员位置的内部类是成员内部类
–在局部位置的内部类是局部内部类
--结构
class A{//外部类
public void show(){
//局部内部类 --> 匿名内部类 !!!
class C{
}
}
//成员内部类 只为 外部类服务 -- 看做是外部类的一个特殊的成员
class B{//内部类
}
}
—
** 堆: new出来的对象(包括实例变量)
** 栈: 局部变量(包括方法的参数)
方法区: class字节码文件(包括方法,静态变量
Lambda表达式1.8
*/TODO Lambda表达式--要求接口里只能有一个抽象方法--优化匿名内部类
*/TODO 语法:(参数列表) -> { 方法体 } ; --练习:没有参数,没有返回值
Inter in2 = () -> { System.out.println("Lambda表达式!"); } ;
in2.save();
*/TODO 语法:(参数列表) -> { 方法体 } ; --练习:有参数,没有返回值
nter2 in3 = (int a) -> { System.out.println(a); } ;
in3.delete(10);
*/TODO 语法:(参数列表) -> { 方法体 } ; --练习:有参数,有返回值(使用return关键字)
Inter3 in4 = (String a,int b) -> { return a+b ; } ;
System.out.println( in4.get("陈子枢",18) );//打印获取到的结果