面向对象和面向过程思想对比
1,客观存在的任何一种事物,都可以看做为程序中的对象。
2,使用面向对象思想可以将复杂的问题简单化。
3,将我们从执行者的位置,变成指挥者。
面向对象类的组成
属性
该事物的各种特征
例如属性:姓名,年龄,毕业院校
行为
该事物存在的功能(能够走的事情)
例如行为:学习,java变成开发
类和对象的关系
类:类是对现实胜过中一类具有共同属性和行为的事物的抽象
对象:是能够看得到摸得到的真实存在的实体
类是对象的描述,对象是类的实体
类的定义
类的组成:属性和行为
属性:在代码中通过成员变量来体现(类中方法的变量)
行为:在代码中通过成员变量来体现(和前面的方法相比去掉了static关键字)
public class 类名{
//成员变量
变量1的数据类型 变量1;
变量2的数据类型 变量2;
//....
//成员方法
方法1;
方法2;
}
对象的使用
创建对象
格式: 类名 对象名 = new 类名();
范例:Student s = new Student();
使用对象
1,使用成员变量
格式:对象名.变量名;
2,使用成员方法
格式:对象名.方法名;
单个对象内存图
两个对象内存图
两个引用指向同一个对象内存图
垃圾回收
当堆内存中,对象或数组产生的地址,通过任何方式都不能找到后,就会被判定为内存垃圾,
垃圾会被java垃圾回收器,空闲的时候自动进行清理。
成员变量和局部变量
区别 | 成员变量 | 局部变量 |
类中位置不同 | 类中方法外 | 方法内或者方法声上(形参) |
内存中位置不同 | 堆内存 | 栈内存 |
生命周期不同 | 随着对象的存在而存在,随着对象的消失而消失 | 随着方法的调用而存在,随着方法的调用完毕而消失 |
初始化值不同 | 有默认的初始化值 | 没有默认的初始化值,必须先定义,赋值,才能使用 |
封装
面向对象三大特征(封装,继承,多态)
隐藏实现细节,仅对外暴露公共过的访问方式
封装常见的体现:
1,私有成员变量,提供setxxx和getxxx方法
2,将代码抽取到方法中,这是对代码的一种封装
3,将属性抽取到类当中,这是对数据的一中封装
封装的好处
1,提高了代码的安全性
2,提高了代码的复用性
Private关键字
是一个权限修饰符
可以修饰成员(成员变量和成员方法)
被Private修饰的成员只能再本类中才能访问
针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰。
提供“set变量名()”方法,用于设置成员变量的值,方法用public修饰。
this关键字
可以调用本类的成员(变量,方法)解决局部变量和成员变量的重名问题。
this;代表所在类的对象应用
方法被那个对象调用,this就代表那个对象。
构造方法
构建,创造对象的时候,所调用的方法
格式:
1,方法名与类名相同,大小写也要一致
2,没有返回值,连void也没有
3,没有具体的返回值(不能由return带回返回结果数据)
执行时机
1,创建对象的时候调用,每创建一次对象,就会执行一次构造方法。
2,不用手动调用构造方法。
构造方法的作用
用于给对象的数据(属性)进行初始化
class Student{
private int age;
public Student(){
age = 18;
}
//set\get方法
}
所有Student对象的age,都是18.
class Student{
private int age;
public Student(){
this.age = 18;
}
//set\get方法
}
this.age代表是成员变量age,这样就不会所有的Strdent对象的age都是18了。
构造方法的注意事项
1,构造方法的创建
如果没有定义构造方法,系统将给出一个默认的无参数的构造方法。
如果定义了构造方法,系统不再提供默认的构造方法。
2,构造方法的重载
如果自定义了带参数的构造方法,还要使用无参数的构造方法,就必须再写一个无参数构造方法。
3,推荐的使用方式
无论是否使用,都手动书写无参数的构造方法,和带参数的构造方法。
标准类制作
1,成员变量
使用private修饰
2,构造方法
提供一个无参数构造方法
提供一个带多个参数的构造方法
3,成员方法
提供每一个成员变量对应的set()/get()
提供一个显示对象信息的show()
4,创建对象并为其他成员变量赋值的两种方式
无参数构造方法创建对象后使用set()赋值
使用带参构造方法直接创建带有属性值的对象
JavaBean类:封装数据。
static关键字
static关键字是静态的意思,是Java中的一种修饰符,可以修饰成员方法,成员变量。
被static修饰的成员变量,叫做静态变量。
被static修饰的成员方法,叫做静态方法。
static修饰的特点
1,被static修饰的成员,会被该类的所有对象【共享】
2,被static修饰的成员,会随着类的加载而加载,优先于对象的纯在
3,多了一种调用方式,在主方法中通过类名进行调用。
静态随着类的加载而加载,优先于对象的存在,非静态需要在创建对象之后,才能使用。
1,静态方法中,只能访问静态的成员(成员变量,成员方法)
2,非静态方法中,可以使用静态成员,也可以使用非静态成员
3,静态方法中 ,没有this关键字(this关键字是当前对象的应用,需要在创建对象之后,才会存在,静态存在的时候,对象可能还没有被创建)
总结:静态方法中,只能访问静态成员,静态中没有this关键字。
继承
继承:让类与类之间产生关系(子父类关系),子类可以使用父类中非私有的成员
继承的格式:
//格式:public class 子类名 extends 父类名{}
//范例
public class zi extends fu{}
//fu:是父类,基类,超类
//zi:子类,派生类
继承的好处和弊端
继承的好处
提高了代码的复用性
提高了代码的维护性
让类与类之间产生了关系,是多态的前提
继承的弊端
继承是侵入性的
减低了代码的灵活性
继承关系,导致子类必须拥有父类非私有属性和方法,让子类自由的世界中多了些约束
增强了代码的耦合性
代码与代码之间纯在关联都可以成为耦合
继承的特点
Java只支持单继承,不支持多继承,但支持多层继承。
继承的成员变量访问特点
在子类方法中访问一个变量
子类局部范围找
子类成员范围找
父类成员范围找
注意:如果子父类中出现了重名的成员变量,就通过就近原则,会优先使用子类的,如果一定要使用父类的,可以通过super关键字,进行区分。
super关键字的用法和this关键字的用法相识
this:代表本类对象的引用
super:代表父类存储空间的标识(可以理解为父类对象引用)
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
this | this.成员变量 访问本类中的成员变量 | this.成员方法(...) 访问本类成员方法 | this(...) 访问本类构造方法 |
super | super.成员变量 访问父类成员变量 | super.成员方法(...) 访问父类成员方法 | super(...) 访问父类构造方法 |
继承中成员方法的访问特点
通过子类对象访问一个方法
子类成员范围找
父类成员范围找
方法重写
方法重写概述
在继承体系中,子类出现了和父类中一模一样的方法声明
方法重写的应用场景
当子类需要父类的功能,而功能主体子类有自己特有内容,可以重写父类中的方法,这样即沿袭了父类的功能,又定义了子类特有的功能
注意:
方法重写:在继承体系中,子类出现了和父类中一模一样的方法声明(方法名,参数列表,返回回值类型)
方法重载:在用一个类中,方法名相同,参数列表不同(类型,数量,默认值的不同),与返回值无关
方法重写注意事项
父类中私有方法不能被重写
父类静态方法,子类必须通过静态方法进行重写,父类非静态方法,子类也必须通过非静态方法进行重写。
静态方法不能被重写!如果子类中,也存在一个方法声明一模一样的方法也可以理解为,子类将父类中的同名方法隐藏了起来,并不是方法重写。
子类重写父类方法时,访问权限必须大于等于父类。
权限修饰符
修饰符 | 同一个类中 | 同一个包中子类无关类 | 不同包的子类 | 不同包的无关类 |
private | true | |||
默认(default) | true | true | ||
protected | true | true | true | |
public | true | true | true | true |
子类自己特有的属性
子类在初始化之前,一定要先完成父类数据的初始化
子类在初始化之前,一定要先访问到父类的构造方法,完成父类数据的初始化
系统在每一个构造方法中,默认隐藏的一句代码super();
继承中构造方法的访问特点
1,子类中所有的构造方法默认都会访问父类中无参的构造方法
2,子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。
子类初始化之前,一定要先完成父类初始化
怎么初始化:
构造方法的第一条语句默认就是:super();
注意:如果我们编写的类,没有手动指定父类,系统会自动继承Object(java中继承体系最顶层的父类)
3,如果父类中没有空参构造方法,只有带参构造方法,
子类通过super,手动调用父类的带参的构造方法
子类通过this去调用本类的其他构造方法,本类其他构造方法再通过super去手动调用父类的带参的构造方法
注意:this(),super()必须方法构造方法的第一行有效语句,并且二者不能共存。
总结:子类中所有的构造方法,默认都会通过super()访问父类中无参的构造方法每一个子类构造方法的第一条语句默认都是:super()。
开发中遵守开闭原则:对扩展内容开放,对修改内容关闭。
抽象类概述
抽象方法:将共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义为抽象方法。
抽象类:如果一个类中存在抽象方法,那么这个类就必须声明为抽象类。
抽象方法的定义格式:
public abstract 返回值类型 方法名(参数列表);
抽象类定义格式:
public abstract class 类名{}
特点:
1,抽象类不能创建对象
2,抽象类中有构造方法
3,抽象类的子类
A:必须要重写父类中所有的抽象方法
B:可以将自己也变成一个抽象类
4,抽象类中的方法
抽象类中可以没有抽象方法,但是有抽象方法的类一定是抽象类
模板设计模式
设计模板是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结
使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性,程序的重要性。
模板设计模式:把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法让使用模板的类(继承抽象的类)去重写抽象方法实现需求。
模板设计模式的优势,模板已经定义了通用结构,使用这只需要惯性自己需要实现的功能即可。
final关键字
final关键字是最终的意思,可以修饰(方法,变量,类)
final修饰的特点
修饰方法:表明该方法时最终方法,不能被重写
修饰变量:表明该变量是常量,不能被再次赋值
修饰类:表明该类是最终类,不能被继承
//常量的命名规范:如果是一个单词,所有字母大写,如果是多个单词,所有字母大写,但是中间需要使用_分隔。
final修饰变量的时候:
基本数据类型变量:其值不能被更改
引用数据类型变量,地址值不能被更改,但是可以修改对象的属性值
final修饰成员变量的时候,对变量初始化的时机:
1,在创建的时候,直接给值
2,在构造方法结束之前,完成赋值
代码块概述与分类
在java中{ }括起来的代码被称伪代码快
分类:
局部代码块
位置:方法中定义
作用:限定变量的生命周期,及早释放,提高内存利用率
构造代码块
位置:类中方法外定义
特点:每次构造方法执行的时候,都会执行代码块中的代码,并且在构造方法执行前执行
作用:将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性。
静态代码块
位置:类中方法外定义
特点:需要通过static关键字修饰,随着类的加载而加载,并且只执行一次
作用:在类加载的时候做一些数据初始化的操作
接口介绍
当一个类中所有的方法都是抽象方法的时候,我们就可以将其定义为接口,接口也是一种引用数据类型,它比抽象类还抽象。
接口存在的两个重要意义
1,规则的定义
2,程序的扩展性
接口的定义和特点
接口用关键字interface来定义
public interface 接口名{}
接口不能实例化
接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名{}
接口的子类(实现类)
要么重写接口中的所有抽象方法
要么就是抽象类
注意:接口和类的实现,可以单实现,也可以多实现
public class 类名 implements 接口1,接口2{}
接口中
成员变量:只能是常量,系统会给出默认的三个关键字
public,static ,final
构造方法:没有
成员方法:只能是抽象方法,系统会默认加入两个关键字
public ,abstract
JDK版本接口成员的特征
允许在接口中定义非抽象方法,但是需要使用关键字”default“修饰,这些方法就是默认方法
作用:解决接口升级的问题
接口中默认方法的定义格式:
public default 放回值类型 方法名 (参数列表){}
接口中默认方法注意事项:
默认方法不是抽象方法,所以不强制重写,但是可以被重写,重写的时候去点default关键字
public可以省略,default不能省略
如果实现了多个接口,多个接口中存在相同的方法声明,子类就必须对该方法进行重写
接口中允许定义static静态方法
接口中静态方法的定义格式:
public static 反回值类型 方法名(参数列表){ }
接口中静态方法的注意事项
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略
接口的使用思路
如果发现一个类中所有的方法都是抽象方法,那么就可以将该类,改进为一个接口
涉及到了接口大面积更新方法,而不像去修饰每一个实现类,就可以将更新的方法,定义为带有方法体的默认方法
希望默认方法调用的更加简洁,可以考虑设计为static静态方法(需要去掉default关键字)
默认方法中出现了重复的代码,可以考虑抽取出一个私有方法。(需要去掉default关键字)
多态
概述
同一个对象,在不同时刻表现出来的不同形态
举例:
我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物 动物 animal = new 猫();
猫在不同时刻表现出来了不同形态,这就是多态
多态的前提和体现
有继承\实现关系
有方法重写
有父类引用指向子类对象
多态中成员访问特点
构造方法:同继承一样,子类会通过super访问父类构造方法
成员变量:编译看左边(父类),执行看左边(父类)
成员方法:编译看左边(父类),执行看右边(子类)
为什么成员变量和成员方法的访问不一样?
因为成员方法有重写,成员变量没有
多态的好处和弊端
多态的好处:提高了程序的扩展性
集体体现:定义方法的时候,使用父类型作为参数,该方法就可以接收这个父类的任意子类对象。
多态的弊端:不能使用子类的特有功能
解决办法:
直接创建子类对象
向下转型
多态中的转型
向上转型
从子到父
父类引用指向子类对象
向下转型
从父到子
父类引用转为子类对象
多态中转型存在的风险
概述:如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现classcastexception;
如果想用子类中的特有方法可以通过向下转型。
instanceof:关键字判断两个类型是否相同,如果是向下转型