Skip to main content

面向对象

面向对象三个阶段:

  • 面向对象分析OOA -- Object Oriented Analysis
    1. 对象: 张三, 王五, 朱六, 你, 我
    2. 抽取出一个类 ---> 人类
    3. 类里面有什么?
    4. 动词 --> 动态特性 --> 方法
    5. 名词 --> 静态特性 --> 属性
  • 面向对象设计OOD -- Object Oriented Design
    1. 先有类, 再有对象
    2. 类: 人类 : Person
    3. 对象 zhangsan, lisi, zhuliu
  • 面向对象编程OOP -- Object Oriented Programming

构造器

  1. 构造器没有返回值, 也不能写void
  2. 构造器的名称和类的名称一样
  3. (String pName, int pAge) 是构造器的形参列表, 规则和成员方法一样
  4. 一个类可以定义多个不同的构造器, 即构造器的重载
  5. 构造器是完成对象的初始化, 并不是创建对象
  6. 在创建对象时,系统自动调用该类的构造器方法
  7. 如果没有定义构造器, 系统会自动给类生产一个无参构造器 也叫默认构造器, 使用javap指令 反变异看看
  8. 一旦定义了自己的构造器,默认构造器就会覆盖,如果想使用无参构造器,除非定义一下: Person(){};
public class Constructor01 {
public static void main(String[] args) {
Person p1 = new Person('lvxl', 30)
System.out.println(p1.name) // lvxl
System.out.println(p1.age) // 30
}
}


class Person {
String name;
int age;

public Person(String pName, int pAge) {
System.out.println('完成对象的初始化')
name = pName;
age = pAge;
}
}

对象的创建分析

class Person{
int age = 90;
String name;
Person(String n, int a) {
name = n;
age = a;
}
}
Person p = new Person("小倩", 20)
  1. 加载Person类信息(Person.class),只会加载一次
  2. 在堆中分配空间(地址)
  3. 完成对象的初始化
    • 默认初始化 age = 0 name = null
    • 显式初始化 age = 90, name = null
    • 构造器初始化 age = 20, name = 小倩
  4. 在对象在堆中的地址,返回给p

this关键字

  1. this关键字可以用来访问本类的属性,方法,构造器
  2. this用于区分当前类的属性和局部变量
  3. 访问成员方法的语法: this.方法名(参数列表);
  4. 访问构造器语法: this(参数列表); 注意只能在构造器中使用,必须放在第一条语句;
  5. this不能在类定义的外部使用,只能在类定义的方法中使用;
class Dog{
String name;
int age;
// 如果构造器的形参吗
public Dog(String dName, int dAge) { // 构造器
name = dName;
age = dAge;
}

public void info () {
System.out.println(name + "\t" + age + "\t")
}
}

包的本质 实际上就是创建不通的文件夹/目录来保存类 包的命名:只能包含数字,字母,下划线,小圆点,不能用数字开头, 不能是关键字或者保留字

代码块

代码块的分类: 普通块, 构造块,静态块,同步块


public class Test {
// 属性
int a;
static int sa;

// 方法
public void a() {
System.out.println("-----a");
{
// 普通块 限制了局部变量的作用范围
System.out.println("这是普通块");
int num = 10;
System.out.println(num);
}
}
public static void b() {
System.out.println("-----b");
}

// 构造器
public Test(int a) {
this.a = a;
}
public Test() {
System.out.println("这是空构造器");
}

// 构造块
{
System.out.println("-----这是构造块");
}
// 静态块
static {
System.out.println("这是静态块");
// 在静态块中只能访问静态属性 和静态方法 ;
System.out.println(sa);
}

// 代码块

public static void main(String[] args) {
Test t = new Test();
t.a();

Test t2 = new Test();
t2.a();

}
}

总结:

  1. 代码块执行顺序:
    • 最先执行静态块,只在类加载的时候执行,所以一般以后要处理初始化信息都放入静态块;一般用于执行全局的初始化操作;
    • 再执行构造块;
    • 再执行构造器;
    • 再执行方法中的普通块;

修饰符

修饰符同一个类同一个包子类所有类
private*
default**
protected***
public****

super

  1. super指的是父类;
  2. super可以修饰属性, 可以修饰方法;在子类中去调用父类属性和方法: (通常情况,super省略不写)
    public class Student extends Person {
    public void a() {
    System.out.println(super.age);
    super.eat()
    }
    }
  3. super修饰构造器, 调用父类的空构造器
    public class Student extends Person {
    public Student() {
    super();
    }
    }
  4. super修饰构造器,super调用父类构造器和this调用子类构造器只能存在一个;因为super修饰构造器要放在第一行,this修饰构造器也要放在第一行。

三大特性

  • 封装 --> 将某些东西进行隐藏,然后提供相应的方式进行获取。
    1. 高内聚: 类的内部数据操作细节自己完成,不允许外部干涉;
    2. 低耦合: 仅对外部暴露少量的方法用于使用;
    3. 提高代码的安全性;
  • 继承
    1. 提高代码的复用性
    2. 父类private修饰的内容,子类实际上也继承了,只是因为封装的特性阻碍了直接调用,但是也提供了间接调用的方法;
    3. 为了以后多态的使用, 是多态的前提;
    4. 一个子类只能继承一个父类。但是可以间接的继承自其他类型;所有的类都直接或者间接的继承自 Object;
  • 多态
    1. 多态与属性无关, 多带纸的是方法的多态, 而不是属性的多态;
    2. 同一方法调用,然后由于对象的不同,会产生不同的行为;
    3. 为了提高代码的扩展性,符合面向对象的设计原则: 开闭原则。 (扩展是开放的,修改是关闭的);

方法的重载

equals 与 ==

  1. ==: 既可以判断基本类型,有可以判断引用类型
  2. ==:如果判断基本类型,判断的是值是否相等
     int a = 10;
    double d= 10.0;
    a == d // true;
  3. ==:如果判断引用类型,判断的是地址是否相等,即判断是不是同一个对象
  4. equals:是Object类中的方法,只能判断引用类型
  5. equals: 默认判断的是地址是否相等,子类中往往重写该方法,用于判断类容是否相等,比如Integer,String

hashCode

  1. 提高具有哈希结构的容器的效率!
  2. 两个引用,如果指定的是同一个对象,则哈希值肯定一样的
  3. 两个引用,如果指向的是不同对象,则哈希值是不一样
  4. 哈希值主要根据地址号来的,不能完全将哈希值等价于地址

抽象类

当父类一些方法不能确定的时候,可以使用abstract关键字类修饰该方法,这个就是抽象方法,用abstract来修饰的类就是抽象类。 抽象类的价值更多用于设计,是设计者设计好后,让子类实现的。

细节:

  1. 抽象类不能实例化;
  2. 抽象类不一定要包含abstract方法,也就是说抽象类可以没有abstract方法
  3. 一旦类包含类了abstract方法,这个类必须声明为abstract
  4. abstract只能修饰类和方法,不能修饰属性和其他;
  5. 抽象类可以有任意成员(抽象类本质还是类),比如:非抽象方法,构造器,静态属性等等。、
  6. 抽象方法不能有主体;
  7. 如果一个类继承类抽象类,则必须实现抽象类的所有抽象方法,除非她自己也声明成类abstract类。