Java的面向对象
面向对象的三大特征:
- 封装
- 继承
- 多态
包名一般使用英文小写 域名倒序
创建一个对象(Cat)
package com.imooc.animal;
/**
* 猫类
*/
public class Cat {
// 成员属性: 昵称,年龄,体重,品种
String name;
int month;
double weight;
String spacies;
public Cat() {
// 定义无参数构造方法
System.out.println("无参数构造方法");
}
// 成员方法: 吃,跑
public void run() {
System.out.println("小猫在跑");
}
public void run(String name) {
// 重载run方法
System.out.println("小猫" + name + "在跑");
}
public void eat() {
System.out.println("小猫在吃");
}
}
实例化对象
package com.imooc.animal;
public class TestCat {
public static void main(String[] args) {
// 实例化对象
Cat one = new Cat();
one.name = "张三";
one.weight = 100;
one.spacies = "加拿大无毛猫";
one.month = 10;
// 调用成员方法
one.run();
one.eat();
System.out.println("月龄:" + one.month);
one.run(one.name);
}
}
- 声明对象 Cat one
- 实例化对象 new Cat();
声明只是在栈空间中声明了一个one对象,但是这个对象的数据是null空的,无法直接使用
实例化对象之后,在内存堆中开辟了一块空间,并且初始化了对象的数据
栈可堆之间通过堆的内存地址相关联,栈的空对象中储存了堆空间的内存地址
每当调用new 去实例化一个对象,会在堆中开辟一个新的空间,即使实例化了两个数据完全相同的
对象,这两个对象的内存地址不同,是不同的两个对象
构造方法是用来初始化对象的数据的,
public Cat(String name,int month,double weight,String spacies){
System.out.println("有参数构造方法");
this.name = name;
this.month = month;
this.weight = weight;
this.spacies = spacies;
}
类内部使用this代表当前实例
单一职责原则
一个类最好只干一件事,具有一个功能
上述的程序中,只将和Cat有关的内容放在Cat类中,将和Test有关的内容放在TestCat中
构造方法
配合new 关键字使用的方法
- 构造方法的方法名和类名一致
- 构造防范无返回值类型
- 参数按照需求来
- 只能在对象实例化的时候调用
- 类中没有显式定义构造方法的时候,系统会自动创建无参数的构造方法
- 一个类中可以有多个构造方法
定义构造方法后,在实例化对象的时候会自动调用相应的构造方法
//调用构造方法
Cat one = new Cat("张三",10,10.1,"中华田园猫")
封装
- 类中的某些信息隐藏在类的内部,不允许外部程序直接获取
- 通过类内部定义的特定方法实现都隐藏信息的访问
- 隐藏信息
- 留出接口
private
关键字定义的信息是外部程序无法直接获取的信息
对应隐藏的属性,需要使用public
定义相应的getter/setter
方法
去访问相应的数据,访问之前可以添加自己的逻辑
package com.imooc.animal;
/**
* 猫类
*/
public class Cat {
// 成员属性: 昵称,年龄,体重,品种
String name;
private int month;
double weight;
String spacies;
public Cat() {
// 定义无参数构造方法
}
public Cat(String name, int month, double weight, String spacies) {
this.name = name;
this.month = month;
this.weight = weight;
this.spacies = spacies;
}
public void setMonth(int n) {
if (n <= 0) {
System.out.println("输入month不合法");
} else {
this.month = n;
}
}
public int getMonth() {
return this.month;
}
}
将month定义成为隐藏属性,需要通过getMonth和setMonth方法来访问这个隐藏数据
,实例化对象之后也无法直接通过访问属性的方式直接访问属性,而是通过定义的两个方法
来间接的访问相应的属性.
包
Java使用包来管理类的,在同一个包内[文件夹]是不允许出现同名的类的
导入包需要使用import xxx.xxx.Cat
或者如果使用某个目录下的所有数据import xxx.xxx.*
- xxx.aaa.Cat
- xxx.bbb.Cat
导入不同包中的同名类会冲突,解决方案
- 在使用的时候,都直接使用全路径
xxx.aaa.Cat one = new xxx.aaa.Cat();
xxx.bbb.Cat two = new xxx.bbb.Cat();
- 一个导包一个使用全路径
import xxx.aaa.Cat;
Cat one = new Cat();
xxx.bbb.Cat two = new xxx.bbb.Cat()
static
关键字定义的静态方法,加载静态信息,通过static
关键字定义的变量,方法都需要以静态
的方式去访问.
用static
关键字,修饰的成员属性是静态成员属性,实例出两个不同的对象后,静态数据是共享同一块内存空间
两个不同的对象的静态属性会同时改变.
静态属性在类第一次加载的时候就会产生,直到所有同类彻底销毁的时候才会释放这段内存,生命周期长
用静态的方式去访问,即用 类名.属性(方法)的方式去访问.
代码块
public void run(){
{
System.out.println("this is ordinary code block")
}// 普通代码块
System.out.println("this is run!")
}
在一个方法内部定义的普通代码块,会在普通代码块中的逻辑执行完毕之后再继续执行外部逻辑
在类内,成员方法外使用的代码块为构造代码块
public class Cat{
{
System.out.println("this is construct Code Block");
}// 构造代码块
public static void main(String[] args){
}
static {
System.out.println("this is static Code Block");
}
}
构造代码块中的逻辑会在构造方法之前先执行完毕,构造代码块也可以有多个,执行顺序即定义顺序
构造代码块用static
修饰之后,变为静态代码块,静态代码块也是在构造实例的时候执行,执行顺序
在构造代码块之前,也可以有多个静态代码块,执行顺序即定义顺序.
注意: 静态代码块只在这个类第一次实例化的时候被调用,而构造代码块,实例化几个对象就调用几次.
场景:
- 构造代码块中可以给成员属性,静态属性赋值,需要被重新初始化的逻辑放在构造代码块之中
- 静态代码块中只能给静态属性赋值,不能给成员属性赋值,只希望被执行一次的逻辑放在静态代码块中