面向对象
万物皆对象
万物皆对象是指我们可以将任何事物都分析出属性和行为,理解为对象
面向对象的两个要素
类:对一些事物的描述,是抽象的,概念上的
对象:是实际存在的该类事物的每个个体,也称之为实例
类和对象的关系
类是对象的抽象,对象是类的具体,由类衍生出对象
/
面向对象程序设计的重点是类的设计
设计类,就是设计类的成员
属性=成员变量=field=域,字段
方法=成员方法=method=函数
/
属性和方法
属性:一些事物共有的特征,称之为属性(也叫实例变量,直接书写在类中)
方法:一些事物共有的动作,称之为方法(分为:实例方法(实例方法没有static关键字),普通方法)
实例(普通)方法的定义格式
public 返回值类型 方法名(形参列表){
}
/
创建类的对象=类的实例化=实例化类
/
怎么样创建对象
类名 对象名=new 类名()
/
如果创建一个类的多个对象,则每个对象都独立的拥有一套类的属性/结构(非static修饰)
/
调用对象的结构:属性,方法
对象.(点)属性
对象.(点)方法(形参)
对象和引用的区别
对象是通过new出来的,在堆内存中存储。
引用是:但凡是变量,并且该变量中保存了内存地址指向了堆内存当中的对象的。
空指针异常只有在什么情况下才会发生
只有在“空引用”访问“实例”相关的,都会出现空指针异常。
类和对象的使用(面向对象思想落地的实现)
1.创建类,设计类的成员
2.创建类的对象
3.通过对象调用对象的结构(对象.(点)属性,对象.(点)方法(形参))
实例变量的特点(与局部变量的区别)定义位置:在类中———方法中
默认值:有默认值,与数组相同———无默认值
作用范围:当前整个类中———当前最近大括号
重名:可以与局部变量重名 局部变量优先 就近原则———不能重名
生命周期:随着对象的的创建而存在 随着对象被垃圾回收而死亡 GC Garbage Collection
存储位置:实例变量存储在堆中———存储在栈中
实例变量在构造方法执行的过程中赋值(new的时候赋值)
main方法能直接访问对象的属性和方法吗
不能直接访问,必须先创建对象
/
引用类型的变量只能存储两类值:null 或 地址值(含变量的类型)
/
有参构造
初始化对象的信息
我们在创建对象的同时,可以给属性赋值,使用有参构造
无参构造是默认存在 如果书写了有参构造 那么默认的无参将被覆盖
如果想要使用 显式的书写
构造方法重载的要求
与普通方法重载规则类似
构造方法都是类名,没有返回值,与访问权限无关
所以只要求,参数列表不同 参数的个数 类型 顺序
this关键字
this关键字 表示当前对象(this是一个引用)
this可以用在实例方法中,也可以使用在构造方法中
this关键字语法:
访问属性 this.属性名
访问方法 this.方法名
this()这种语法只能出现在构造方法中的第一行,只能使用一次,表示当前构造方法调用本类其他的构造方法,目的是代码复用。
this点大部分情况下可以省略,但是用来区分局部变量和实例变量的时候不能省略
this不能用于静态方法中
static关键字
(所有static关键字修饰的都是类相关的,类级别的)
static可以用来修饰
成员变量→静态变量,可以直接通过类名访问
成员方法→静态方法,可以直接通过类名访问
代码块→静态代码块,当Java虚拟机加载类时,就会执行该代码块
内部类
/
实例:随着对象的创建而加载
静态:随着类的加载而加载
/
static修饰变量
被static修饰的变量在内存中只存在一份,因为类只加载一次,存在方法区的静态域中,可以用于数据共享,实现多个实例之间的数据传递
类内部,可在任何方法内直接访问静态变量
其他类中,可以直接通过类名访问
static修饰方法
静态方法:可直接通过类名访问
静态方法中不能使用this和super
不能直接访问所属类的实例变量和实例方法
可直接访问类的静态变量和静态方法
静态方法必须被实现(方法里面要有代码)
实例方法:通过实例访问
可直接访问所属类的静态变量、静态方法、实例变量和实例方法
static修饰代码块
静态代码块
随着类被加载执行 多个静态代码块按照书写顺序执行 每个只执行一次 因为类只加载一次
静态代码块用于实现一些前置的操作 比如数据初始化 等(如同手机开机动画只进行一次)
普通(实例)代码块
每new一次对象 执行一次
总结
所有的实例相关的都是先创建对象,通过”引用点“访问
所有的静态相关的都是直 接采用”类名点“访问
访问规则
1.静态与静态直接调用
2.静态访问非静态 必须先new对象
3.非静态的访问静态的 直接调用
类加载的过程
名词解释
方法区:是JDK提供的一个规范,符合这个规范即可称之为方法区
元空间:方法区的实现,JDK1.8叫元空间,用来加载类信息文件,初始化静态相关信息等
永久代:JDK1.7 之前叫永久代,方法区的实现
加载过程
1.当我们第一次访问一个类时,JVM先在方法区查看是否有加载当前类信息文件
如果有,在堆中开辟空间,将栈中的引用指向堆中的空间
如果没有,先加载类信息文件,然后在堆中开辟空间,将栈中的引用指向堆中的空间
类体{
实例变量,静态变量
构造方法
实例代码块,静态代码块
实例方法,静态方法
}
封装
概念和思想
封装 :
1.将类的信息尽可能的隐藏在类的内部 不让外部直接访问
使用private修饰属性即可
被private修饰的属性表示只能在本类中访问 其他类不能访问
2.而是提供一对公开的setter和getter方法用于访问属性
setter方法用于设置属性值
getter方法用于获取属性值
封装的作用,实现封装的步骤?
让使用者正确的使用系统,减少构建大型系统的风险
增加代码的可重用性
降低了程序的耦合度
属性私有 方法公开
使用private修饰属性
访问权限修饰符
类的访问修饰符:
1.public 本项目中任何位置都可以访问
2.默认不写 本包中可以访问
类成员/结构(属性和方法和构造方法和内部类)的访问修饰符:
1.private 表示私有的本类中可以访问
2.默认不写的 本包中可以访问
3.protected 受保护的 本类中 本包中 子类中
4.public 本项目中任何位置都可以访问
所谓javaBean,是指符合如下标准的Java类
1.类是公共的
2.有一个公共的无参的构造器
3.有属性,且有对应的get,set方法
继承
继承的作用
基本作用:子类继承父类,可以避免代码冗余,代码可以有效得到复用,便于功能的扩展
主要(重要)作用:因为有了继承关系,才有了后期的方法覆盖和多态机制
继承
Java中只支持单根继承,即一个类只能有一个直接父类,但有的时候会产生间接继承的效果,一个父类可以派生多个子类。
子类与父类是is-a的关系,子类是父类
父子类信息编写原则:
父类中编写共有的属性和行为
子类中编写独有的属性和行为
方法重写
1.父子类之间的
2.方法名称相同
3.参数列表相同
4.访问权限不能严于父类 不能窄化父类的访问权限
子类不能重写父类中声明为private权限的方法,如果写了,属于子类独有的方法
通过多态机制外部无法访问到父类已经私有化的方法
5.返回值相同 或者是其子类
返回值类型的子类
基本数据类型必须返回相同的数据类型
6.父类的静态方法可以被继承 但是不能被重写 非静态方法不能重写为静态方法
子类书写与父类相同的静态方法为子类隐藏了父类的静态方法
7.不能抛出比父类更多的异常
@Override注解 此注解可以用于子类的方法上 表示此方法为重写父类的方法 如果没有符合以上重写的规则 那么将编译报错
注意事项
- 方法覆盖只是针对与方法,和属性无关
- 私有方法无法覆盖
- 构造方法不能被继承,所以构造方法也不能被覆盖
- 方法覆盖只是针对于实例方法,静态方法覆盖没有意义
super关键字
super关键字:表示当前对象的那部分父类型特征
可以访问,父类访问权限允许的:方法,属性,构造方法
super能出现在实例方法和构造方法中。
super的语法是
super.属性
super.方法
super. 大部分情况下是可以省略的。父类和子类中有同名属性,或者说有同样的方法,想在子类中访问父类的,super. 不能省略。
super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
super不能使用在静态方法中。
(super()的作用是初始化当前对象的父类特征,并不是创建新对象,实际上对象只创建了一个)
构造方法
创建子类对象时,默认调用父类的无参构造方法
除非子类显式的调用父类的有参构造方法
子类必须调用父类的构造方法 无参或者有参必须调用一个
重要的结论
当一个构造方法第一行:
既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法。
所以必须保证父类的无参数构造方法是存在的。
/
super 不是引用。super也不保存内存地址,super也不指向任何对象。
super 只是代表当前对象内部的那一块父类型的特征。
/
Object类
Object是所有的类的父类,所有的类将默认继承自此类
此类中提供了一些常用的方法,实际开发中我们经常重写这些方法
重写toString方法
我们直接打印一个对象将默认调用此对象的toString方法,返回值为包名类名+@+哈希值
如果我们不想要这个效果,可以重写toString方法
多态
多态的实现方式:
1.父类作为形参 实参为子类类型
2.父类作为返回值 实际返回值类型为子类
多态的表现形式
父类引用指向子类对象
1.向上转型:此时可以调用继承父类的方法与重写父类的方法,不能访问子类独有的方法
2.向下转型:此时可以调用子类独有的方法,以及继承父类和重写父类的方法
是指将指向子类对象的父类引用转换为子类类型,而不是将父类强制转换为子类
多态在开发中的作用是
降低程序耦合度,提高程序的扩展力
Instanceof关键字
判断左侧类型是否属于右侧类型,返回值为布尔类型
开发软件的原则
七大原则的最基本的原则:OCP(对扩展开放,对修改关闭)
目的是:降低程序耦合度,提高程序扩展力
面向抽象编程,不建议面向具体编程
方法覆盖需要和多态机制联合起来使用才有意义。
假设没有多态机制,只有方法覆盖机制,你觉得有意义吗?
没有多态机制的话,方法覆盖可有可无。
没有多态机制,方法覆盖也可以没有,如果父类的方法无法满足
子类业务需求的时候,子类完全可以定义一个全新的方法。
方法覆盖和多态不能分开。
私有方法无法被覆盖
因为外部类无法访问到父类中的私有方法,自然无法通过编译进而去通过多态去调用子类重写的方法
静态方法存在方法覆盖吗
多态自然就和对象有关系了。
而静态方法的执行不需要对象。
所以,一般情况下,我们会说静态方法“不存在”方法覆盖。
不探讨静态方法的覆盖。
静态方法可以使用“引用.”来调用
虽然使用“引用.”来调用,但是和对象无关。
总结两句话
私有不能覆盖。
静态不谈覆盖。