明确: 面向对象,面向过程 等是一种编程思想
思想的概念: 是人们普遍能接受的思维方式。
面向过程 : 将需求 按照步骤一步步划分,一步步执行。 典型语言:C语言
面向对象 :将自己的事情交给别人(对象) 来做
面向函数 : 不考虑对象,只针对功能本身 例如:JDK1.8提供的新特性
面向对象的三大特点
1. 懒人的思想,将自己的事情交给对象来做。
2. 将我们由执行者变成了调用者
3. 将复杂的事情简单化,将简单的事情变得更加简单
面向对象15字总结:
服务员点单
万物皆对象
对象调方法(资源)
类和对象的关系
类的概念:一类事务的统称 例如:狗类
使用场景: 作为对象的图纸
对象的概念:一类事务的具体的实例 例如:我家的黄色皮肤的,2岁的,名字叫:阿黄的中华田园犬
使用场景: 作为类的具体的实例
面向对象编程
1. 定义事物描述类 画图纸
2. 创建实例对象 生产实例
3. 对象调方法
1. 定义事物描述类的步骤
属性:这一类事物共有的特性
定义格式: public 数据类型 属性名;
例如: public String name;
例如: public int age;
例如: public double price;
行为: 这一类事物共有的行为
定义格式:参考方法的格式
public (不要static) 返回值类型 方法名(形参列表){
方法体;
return 值;
}
2. 定义一个测试类
-- 使用new关键字创建事物描述类的对象
-- 使用对象调成员
成员变量和局部变量的区别
1. 在代码中的位置不同:
成员变量:在类中方法外
局部变量: 在方法内
2. 作用范围的不同:
成员变量: 在整个类中都可以使用
局部变量: 只能在当前方法中使用
3. 在内存空间中的位置不同:
成员变量:在堆的对象空间中
局部变量: 在栈内存方法的空间中
4. 默认值不同:
成员变量:未赋值,有对应的默认值
局部变量:未赋值没有默认值
5. 生命周期不同:
成员变量: 随着对象的创建而出生, 对象被GC空闲回收时死亡
局部变量: 方法被调用时出生, 方法执行完毕弹栈时死亡
6. 在IDEA中颜色不同:
成员变量:被使用是细紫色
局部变量:被使用白色
辅助记忆:
1. 因为在代码中的位置不同,所以作用范围不同
2. 因为在内存空间中的位置不同,所以默认值不同
构造方法的重载:
明确: 构造方法也是一种特殊的方法
说明: 1. 同一个类中,构造方法名都相同,但是参数列表不同 --- 构造方法的重载
2. 在实际开发中构造方法一般只写:无参 和 满参构造
匿名对象
明确: 当使用new关键创建对象时,创建出来的对象可以是匿名的,也可以非匿名
例如:
Phone phone = new Phone(); // 有名字的对象
new Phone(); // 没有名字的对象 -- 匿名对象
匿名对象的使用场景:
当对象只需要使用一次时,建议使用匿名对象
匿名对象作为方法的实参传递
权限修饰符
public : 公开的公共的
protected : 受保护的
default : 默认的 说明: 不写权限,默认是default
private : 私有的
权限范围大小: public > protected > default > private
重点掌握: public 和 private即可
明确: 在定义食物描述类时,属性一般使用private修饰,行为一般使用:public
说明:
属性私有的作用: 不让通过对象直接为属性赋值,必须通过调用对应的setXXX()修改属性值,调用getXXX()获取属性值,提高属性赋值的安全性。
行为公有的作用: 让对象直接调用行为,提供对外访问的窗口
总结:
1. 事物描述类中:属性都私有(private), 行为都公有(public)
2. 事物描述类中的成员:
-- 私有属性
-- 公有行为
-- 构造方法
-- setXxx() and getXxx() 方法
构造方法
分类:
-- 无参构造:
格式: public 构造方法名(){}
调用: 使用new关键字调用
例如: new 构造方法名();
-- 有参构造:
格式: public 构造方法名(形式参数列表){
将实际参数赋值给对应的成员变量 : this.age = age;
}
调用: 使用new关键字调用
例如: new 构造方法名("张三",29,"男",...);
注意事项:
1. 构造方法声明时,不能使用static修饰
2. 构造方法的方法名必须和类名完全一致
3. 构造方法没有返回值这一项,连void都不能写,因为使用构造方法就是为当前对象的成员变量赋值的
4. 使用new关键字创建对象有四个步骤:
-- 1. 使用new 关键字开辟对象空间,分配内存地址值
-- 2. 将对象进行默认初始化: 属性值赋默认值
-- 3. 调用构造方法 进行显示初始化: 将实际参数值赋值给对应的成员变量
-- 4. 返回对象:返回对象在堆中的内存地址值
封装
面向对象的三大特性: 封装,继承,多态
封装:将属性隐藏(私有) ,只提供一个统一的对外访问的窗口----> 对象
封装的形式: 1. 有参构造
2. 无参构造 + setter
/*import java.lang.String;*/
// 导包格式: import 包名1.包名2....类名;
// 静态导入(static import)是在JDK1.5新增加的功能
静态代码块
构造代码块:
格式: {}
位置:类中方法外
执行特点:每次调用构造方法之前执行,每调用一次构造方法就执行一次构造代码块
作用: 可以给对象做默认初始化操作
静态代码块:
格式:static{}
位置: 类中方法外
执行特点:当类加载时执行,只执行一次。
类加载时,自动执行
作用: 当类第一次加载时,可以直接为静态成员赋值
执行优先级:
静态代码块 > new > 构造代码块 > 构造方法
静态成员的访问
在非静态方法中: 不管是静态成员还是非静态成员都可以访问
在静态方法中: 只能访问本类的其他静态成员,不能访问非静态
这是为什么? 核心思想:跟资源的加载先后顺序有关
当类加载时,此时只有静态成员,此时在静态方法中访问不到非静态成员,因为他们还没创建出来
当非静态方法所对应的对象创建时,此时静态和非静态成员都加载好了。
为什么在静态方法中不能有this?
因为在静态方法加载时,此时内存中没有该类的对象,this是本类对象的引用,找不到对象,所以会报错
this关键字
明确: this他只能用在行为:(非静态方法)中使用
定义: this是本类对象的引用
辅助记忆: 哪个对象调用this所在的方法,this就代表那个对象 , this里面就是本类对象的地址值
this如何用?
this.属性: 掌握
直接使用变量名: 优先找局部变量, 局部变量没有再找成员变量 -- 就近原则
使用this.变量名 : 直接拿成员变量对应的值
说明: 以后只要想获得成员变量,都用this.变量名
this.行为: 了解
明确: 方法只能并列不能包含和嵌套,所以事物描述类中的方法都说得是:成员方法 , 没有局部方法
this.方法名(实参) : 一般省略this , 直接写成方法名(实参)
this() / this(实参) :调用本类其他的构造方法 了解
注意事项: 只能将 this() / this(实参) 放在本类构造方法的第一行
优点: 提高代码复用性,可读性
继承
关键字:关键字 extends
继承定义: 将多个子类中非私有共性成员向上抽取到一个公共的父类中,由子类去继承。
继承: 描述了类与类之间的关系(父子关系)
父类:
格式: public class 父类名{}
子类:
格式: public class 子类名 extends 父类名{}
继承的特点:
1. 只能单一继承, 多层继承 单一继承:只有一个亲爹 多层继承 : 亲爹还有亲爹
2. 只能继承父类中非私有的成员
3. 子类知道直接父类,直接父类不知道子类 解释说明: java中的父类是渣男
4. 子类要加载优先加载父类 辅助理解: 先有爹后由子
继承的优点
1、继承的出现提高了代码的复用性,提高软件开发效率。
2、继承的出现让类与类之间产生了关系。
继承的内存图:
继承中对象的内存图:
super关键字:
定义:本类对象的父引用 辅助理解:只能指向本类对象的父对象
super的使用:
super.属性名 : 就近原则: 当直接使用变量名是,先找局部变量 , 再找子类成员变量 , 找父类成员变量,所有的父类都没有就报错
super.方法名(实参): 执行父类中的方法
super(); / super(实参); : 子类调用父类的构造方法
注意事项: 子类的构造方法中没有写任何调用父类构造方法的语句,默认会在子类构造方法的第一行加上:super();
子类的构造方法中只能在第一行调用父类构造方法
说明: 一般先写父类构造方法 , 再去写子类构造方法去继承父类的构造方法
方法的重写
定义: 当父类中的方法的方法体,对于子类不适用时,子类可以重写该方法的方法体
重写方法的格式要求:必须和父类中被重写方法的声明格式一毛一样
重写方法的标记: @Override
标记的作用:约束重写的方法的格式必须和父类被重写方格式一致,否则标记报错
方法的重写的优点: 提高方法的多用性
请说说: overload 和 override 的区别:
overload : 是方法的重载 , 要求在同一个类中方法名相同,参数列表不同
override : 是方法的重写,要求在继承关系下,子类重写父类中的方法时格式要保持一致。
继承关系下成员的访问特点
-- 子类对象调用:
子类对象调属性 : 优先访问子类,子类没有找父类
子类对象调行为 : 优先访问子类,子类没有找父类
子类对象调静态成员 : 优先访问子类,子类没有找父类
-- 父类对象调用:
父类对象调用属性,行为,静态成员都只能访问父类的,不能访问子类的。
辅助记忆: 葵花宝典
前提: 要有继承关系,并且看到对象调成员:
1. 对象调属性: 编译看左边运行看左边
编译看左边 : 看左边的类中是否有这个属性,如果有就不报错,没有就报错
运行看左边 : 拿运行结果从左边类中拿
Zi zi = new Zi();
2. 对象调行为: 编译看左边运行看右边
3. 对象调静态方法: 编译看左边运行看左边
final关键字
含义: final 最终的,最后的,不能改变的 , 没有后代的(被阉割了)
final修饰类:被final修饰的类,不能被继承
使用开发中: 一般工具类被final修饰, JDK中提供的常用类例如: Integer , String
final修饰方法:被final修饰的行为,不能被重写
final修饰属性:被final修饰的成员变量,就是自定义常量,值不能改
例如:
public static final int NUM = 10; psfi
public static final String STR = "java"; psfs
Object类
说明: Object类是所有类的基类 -- 任何一个类都直接或者间接继承了Object类
明确: 如果一个类没有写任何继承关系,默认继承于:Object
介绍: Object类中常用的方法
Class getClass() : 返回对象的模板(类的字节码)
int hashCode() : 返回对象根据内存地址计算的hash值 --- 很大的整数
String toString() : 对象的模板的全类名 + "@" + 对象内存地址的hash的16进制字符除串
equals() : 比较两个对象的内存地址值是否相同
问题一: 比较两个狗对象:dog1 , dog2 ,当属性都相同就认为两个对象相同:
解决办法: 在子类中重写equals()
判定一个对象相同: 1. hash值相同 -- hashCode() 2. 属性相同 -- equals()
问题二:直接打印对象,想看到属性内容?
解决办法: 重写toString()