设计类关系需要遵循:高内聚低耦合
耦合度:紧密 继承(实现)>包含>依赖
类与类之间有三种关系
- A is-a B 泛化(继承 实现)
- A has-a B 包含(组合 聚合 关联)
- A use-a B 依赖 (依赖)need-a
is-a 继承
1、子类继承父类,用关键字extends,可以调用父类中的(public protected)属性和方法当做自己的来使用
eg:
Animal .java
public class Animal {
public String name;
public void eat(){
System.out.println("动物的吃饭方法");
}
public void sleep( ) {
System.out.println("动物的睡觉方法");
}
}
Person .java
public class Person extends Animal{}
Test.java
public class Test {
public static void main(String[] args){
//调用Person方法
Person p = new Person();
//通过p调用Person中的属性、方法
p.name = "优秀";
p.eat();//动物的吃饭方法
p.sleep();//动物的睡觉方法
}
}
2、子类可以添加自己独有的属性或方法
eg:
Animal .java
public class Animal {
public String name;
public void eat(){
System.out.println("动物的吃饭方法");
}
public void sleep( ) {
System.out.println("动物的睡觉方法");
}
}
Person .java
public class Person extends Animal{
//添加一些独有的属性或者方法
public void study(){
System.out.println("人类的学习方法");
}
}
Test.java
public class Test {
public static void main(String[] args){
//调用Person方法
Person p = new Person();
//通过p调用Person中的属性、方法
p.name = "优秀";
p.eat();//动物的吃饭方法
p.sleep();//动物的睡觉方法
p.study();//人类的学习方法
}
}
3、父类继承过来的方法不能满足子类要求,可以在子类重写override(覆盖)父类方法
eg:
Animal .java
public class Animal {
public String name;
public void eat(){
System.out.println("动物的吃饭方法");
}
public void sleep( ) {
System.out.println("动物的睡觉方法");
}
}
Person .java
public class Person extends Animal{
//添加一些独有的属性或者方法
public void study(){
System.out.println("人类的学习方法");
}
//重写(override)Animal中eat()方法
public void eat(){
System.out.println("人类的吃饭方法");
}
}
Test.java
public class Test {
public static void main(String[] args){
//调用Person方法
Person p = new Person();
//通过p调用Person中的属性、方法
p.name = "优秀";
p.eat();//人类的吃饭方法
p.sleep();//动物的睡觉方法
p.study();//人类的学习方法
}
}
4、如果不使用extends,每一个类都默认继承Object类(可以理解为Object是任何一个引用类型的父类);如果使用extends继承后面的父类
5、继承是单个存在的(单继承),每一个类只能有一个继承类,目的是让类变得更安全;可以通过传递的方式实现多继承的效果
重写和重载的区别
方法重写override | 方法重载overload | |
---|---|---|
类 | 产生两个继承关系的类,子类重写父类方法 | 一个类中的一组方法 |
权限修饰符 | (public>protected>默认不写>private)子类可以大于等于父类 | 没有要求 |
特征修饰符 | 父类是final(子类不能重写)、static(不存在重写)、abstract(必须重写,否则子类是抽象类) | 没有要求 |
返回值类型 | 子类可以小于等于父类 | 没有要求 |
方法名字 | 子类名字与父类一致 | 每一个方法名一致 |
参数列表 | 子类必须与父类一致 | 每一个方法参数必须不一致(类型、个数、顺序) |
抛出异常 | 父类抛出编译时异常,子类抛出异常个数少于等于父类,子类抛出异常类型小于等于父类 | 没有要求 |
方法体 | 子类方法内容与父类不一致 | 每一个重载方法执行过程不一致 |
Object类中的方法
hashCode()
把对象内存中的地址经过计算得到一个int整数
源码:public native int hashCode();
equals()
用来比较两个对象的内容,Object默认效果是==
"=="可以比较基本数据类型(值),也可以比较引用数据类型(地址)
equals()方法默认比较地址,如果想要改变规则,需要进行重写
源码:public boolean equals(Object obj){return (this == obj) }
toString()
打印输出时将对象变成String字符串
源码:public String toString(){ return getClass().getName()+"@"+Integer.toHexString(hashCode());}
getClass()
获取对象对应类的类映射(反射机制):加载到方法区中的类模板
wait()
线程进入等待状态,存在重载
notify()
线程唤醒
notifyAll()
全部唤醒
finalize()
权限修饰符是protected,对象被GC回收时,默认执行
源码:protected void finalize(){}
clone()
权限修饰符是protected,克隆对象
this和super的使用
都指代对象
- this指代当前执行方法时的对象,不一定是当前类的对象,有可能是当前类父类的对象
- super指代执行当前方法时对象的父类对象
都能调用一般属性、方法
- 可以放在类成员的任意位置
- 调用一般方法时可以来回互相调用(写法 编译好用) 执行时可能产生问题(StackOverflowError)
可以调用构造方法(放在第一行)
- 构造方法之间不能来回调用(编译不好用)
- this和super在构造方法中调用另一个类的构造方法不能同时出现在第一行,如果不写,默认第一行是super