回忆
- 面向对象的思维方式
- 抽取对象(名词法)
- 分析对象的特征和行为
- 分析对象之间的关系
创建对象,指挥对象做事情
- Java对面向对象的支持
class 类名{}
类 对应 面向对象中提到的对象成员变量
对应类中的特征数据类型 变量名
- [封装]
private 数据类型 变量名
成员方法
对应类中的行为去掉static修饰符
public 返回值类型 方法名(参数类型 参数名.....){}
构造方法
是一种特殊的方法,用于构造这个对象没有返回值类型
且方法名必须是类名
public 类名(参数类型 参数名.....)
- 构造方法可以重载
- 构造方法可以利用
this()
的形式复用代码 - 有些时候
public
修饰符也会声明为其它 ,比如private
- 比如产生单例的对象
- 比如定义了一个工具类
- 默认情况下,Java会给每个类提供一个公共无参的构造方法
- 如果你明确定义了任何一个构造方法时,默认的公共无参的构造方法就不再提供了。
- 关于对象之间的关系,往往是通过
参数类型
来进行关联的。- 当类作为方法参数的时候(本质上是引用类型)
- 调用前后,地址不变
- 如果方法执行过程中,改变了内容,调用后体现的是最新的内容
- 当类作为方法参数的时候(本质上是引用类型)
- 对象的创建(也称为: “实例化”)
new 构造方法()
来创建一个对象的实例- 匿名对象,构造完之后没有赋值
- 仅使用一次的时候
- 作为方法参数传递的时候。
- 使用对象
- 访问成员变量
对象名.变量名
- 访问成员方法
对象名.方法名()
- 【封装】不推荐直接在类的外部操作成员变量。而是通过getter和setter方法来进行的
- 命名规范
- 其它类型
public 数据类型 get变量名首字母大写(){}
public void set变量名首字母大写(数据类型 变量名){}
- boolean类型
public boolean is变量名首字母大写(){}
public void set变量名首字母大写(boolean 变量名){}
- 当成员变量名和局部变量名冲突时,必须使用
this
关键字来区分。 - 因为,默认Java采用的是就近原则。
- 访问成员变量
- 成员变量和局部变量的区别
- 定义的位置不同
- 成员变量: 在类中,方法外
- 局部变量:方法参数,或方法体内
- 内存中的位置不同
- 成员变量: 堆内存
- 局部变量:栈内存
- 初始化不同
- 成员变量:有默认值
- 局部变量:没有默认值,必须赋值后才能使用
- 生命周期不同
- 成员变量: 等待垃圾回收
- 局部变量:脱离作用域直接销毁
- 定义的位置不同
class 类名{
private 数据类型 变量名;
//....
//alt + insert
//构造方法
public 类名(参数类型 参数名,....){
}
//...
//成员方法
public 返回值类型 方法名(参数类型 参数名,....){
}
//...
}
static 关键字
目前看到它的效果:
- 我们以前
public static
定义的方法,在 main 方法中可以直接调用。 - 工具类中
public static
定义的方法 , 在其它类的main方法中类名.方法()
的形式调用。
其实这个 static
关键字,表示静态的意思。它是一个修饰符,可以用来修饰类中的变量和方法。
一旦加了static关键字,特点:
- 随着类的加载而加载。
- JVM运行一个Java程序的时候,它会先将 .class 文件中的信息加载到内存中。在这个时刻我们的静态修饰的成员已经在内存中被初始化了。
- 它先于对象而存在的。
- 被static修饰的这些方法或变量,其实并不属于某个对象,而是大家共享。
- 你将来自己要不要加static,最关键的一条指标。
- static修饰的方法或变量,既可以通过类直接访问(推荐),也可以通过对象来访问(不推荐)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JJVY4rwh-1592476483464)(imges/image-20200618103615545.png)]
注意事项
在静态的方法中,只能访问静态的内容(变量、方法),不能访问成员变量、或成员方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mpRd1qKK-1592476483467)(imges/image-20200618103744132.png)]
静态的方法中没有this关键字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E6Uj09Tj-1592476483469)(imges/image-20200618103938172.png)]
内存结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fdgkZaZ4-1592476483471)(imges/image-20200618105820713.png)]
静态变量和成员变量的区别
- 所属不同
- 静态变量:属于类,它是一个类级变量
- 成员变量:属于对象,它是对象级别的变量
- 内存中的位置不同
- 静态变量:存放于方法区的静态区
- 成员变量:存放于堆内存
- 内存中出现的时机不同
- 静态变量:随着类加载而创建 , 随着JVM的退出而销毁。
- 成员变量: 只有new对象的时候才会创建 , 随着对象的销毁而销毁。
- 调用方式不同
- 静态变量:既可以通过类名调用,也可以通过对象名调用
- 成员变量:只可以通过对象名调用。
main方法是静态的: 能理解吗?
因为执行时,没有任何对象的创建。所以main方法必须是静态的。
工具类是静态的。
参见 Math 类的源码。
JavaDoc的生成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hJYf1diE-1592476483473)(imges/image-20200618144347345.png)]
jdk中提供的这个工具就是用来根据Java代码中的文档注释来生成帮助手册。
在IDE中,可以方便的进行此项工作。
/**
* 定义一个Demo类,提供一个两个数求和的方法,测试。
* @author 作者是谁
* @since 1.0
* @see _2Test
*/
public class _1Test {
public static void main(String[] args) {
System.out.println(sum(2,3));
int a = sum(3, 4);
System.out.println(a);
}
/**
* 这个方法是进行两个整数的求和
* <pre>
* public static void main(){
*
*
* }
* </pre>
* 请使用XXX来替代。
* @param a 这是第一个整数
* @param b 这是第二个整数
* @return 这是两个数加完以后的int型整数
* @see _3Emp#getName()
*/
// @Deprecated
public static int sum(int a, int b){
return a+b;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zJGKrKXX-1592476483476)(imges/image-20200618145237212.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p0nkJPtG-1592476483478)(imges/image-20200618145724358.png)]
以Math类为例,自己测一遍它给的所有方法。
代码块
使用 {}
括起来的代码称为代码块。根据它出现在Java文件中的位置的不同:
- 局部代码块
- 构造代码块
- 静态代码块
- 同步代码块(多线程再说)
局部代码块
出现在方法体中。
作用: 限定变量的生命周期,及早释放,提高内存利用率。
public static void main(String[] args) {
int a = 10;
//想定义代码块,就用大括号
{
//内层作用域,可以看到外层已经定义的变量
// int a=20;//不允许
int b =20;
}
//当脱离了作用域,局部代码块中定义的那些变量都被销毁
int b = 20;//允许的
}
构造代码块
出现在类中、方法外(成员的位置)
作用:在对象创建过程中,就会执行构造代码块中的代码。可以将一些通用的构造逻辑写在这里。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xIrWszLJ-1592476483481)(imges/image-20200618162458451.png)]
- 构造代码块会先于构造方法的执行而执行
- 当直接对成员变量赋值时,此赋值操作会先于构造代码块的执行而执行。
静态代码块
出现在类中、方法外(成员位置),只不过是添加了 static
修饰符。
作用: 当此类被JVM加载的时候,就会执行静态代码块中的逻辑。
所以,适合放置一些全局的初始化逻辑。
static{
}
- 静态代码块,在程序执行期间有且仅执行一次。
- 静态代码块中仅能访问静态的成员(静态变量、静态的方法)
- 构造代码块中既可以访问静态的内容,也可以访问成员变量和成员方法。
继承
继承首先是一种代码复用的体现。
它会分析出共同点,然后将相同的逻辑定义在一个类中。
以学生和老师为例:
比如说要定义一个学生对象:
属性:
姓名
年龄
学号
性别
行为:
吃
学习
睡觉
在比如要定义一个老师类:
属性:
姓名
性别
年龄
工号
行为:
吃
睡觉
讲课
共同点(人):
属性:
姓名
年龄
性别
行为:
吃
睡
让老师和学生 继承 人,这样的话,它里面定义的哪些属性和行为就天生具备了。
继承的格式:
class 子类 extends 父类{
}
继承的好处:
- 提高了代码的复用性
- 提高了代码的可维护性
- 通过继承其实父类和子类、子类和子类之间产生了关系。而这个关系时多态的前提。
Java中继承的特点
- Java中只支持单继承
- 一个类最多只能有一个父类。
- 多个类可以继承同一个父类
- Java支持多层继承
继承中的注意事项
- 继承只能继承父类中非私有的成员。
- 构造方法不能被继承。
- 子类必须通过
super
关键字来调用父类的构造方法。
- 子类必须通过
- 不要为了继承而继承。
- 当问题中出现
is a
的关系的时候,考虑用继承 - 水果和苹果。
- 人和学生。
- 当问题中出现
继承中成员变量的关系
- 当子类中的成员变量和父类中非私有的成员变量同名时,默认访问的是子类中的成员变量。如果确实要访问父类的,需要配合 super关键字。
关于super
super.成员变量;//父类继承下来的成员变量
super(...);//调用父类的构造方法
super.成员方法();//调用父类继承下来的成员方法。
描述学生和工人这两个类。将他们的共性 name 和 age抽取出来放在父类中。提供相应的get和set方法。
同时:要求创建学生和工人是必须指定name和age。