类和类之间的关系
A is-a B 泛化
A has-a B 包含(组合 聚合 关联)
A use-a B 依赖(need-a)
继承
条件: 只要得有两个类:子类、父类
- 子类继承父类,通过一个关键字:extends
package extendsRleationIsA;
/**
* @class 动物的归类
*
*/
public class Animal {
//属性
public String name;
//方法
public void eat(){
System.out.printf("吃饭的方法………………………………………………");
}
public void sleep(){
System.out.printf("动物睡觉的方法……………………………………");
}
}
package extendsRleationIsA;
/**
* @class 表示Person继承了Animal属性方法通过Java的关键字extends
*/
public class Person extends Animal {
}
-
子类可以调用父类中的(public protected(受保护的))属性方法 当作自己的来使用
-
子类可以添加自己独有的属性和方法的
-
子类从父类继承过来的方法不能满足子类的需求,可以在子类中重写父类的方法
-
每一个类都有一个默认继承关系的(Object)类,如果写了extends就继承我写的那个类
-
Java中继承是单个存在的(单继承)每一个类只能有一个继承类(extends关键字后面只能写一个类)Java单继承好处在于更清晰看到代码
- 可以通过传递的方式实现多继承 多实现interface接口概念
-
继承在内存中存储形式
- 代码演示
//Animal类 public class Animal{ //Animal的构造方法 public void Animal(){ System.out.printnl("Animal的构造方法…………………………"); } public void eat(){ System.out.println("动物吃饭的方法………………………………"); } } //Person类 public class Person{ public void Person(){ System.out.print("Person的构造方法………………………………"); } //重写父类当中的eat方法 public eat(){ System.out.println("Person吃饭的方法…………………………"); } } //程序的入口类 public class RunMain(){ public static void main(String [] args){ //加载类的模板的过程 //Person -- Animal -- Object Person person = new Person(); /** *程序执行完成为什么先调的是Animal的构造方法而不是Prson的构造方法 */ person.hasCode(); person.eat();//因为重写过后在内存空间里面先找Person模板类里面有Animal、Object、Person 发现Person自己有eat方法就直接调用了后面也没有调用所有加载出来(Person吃饭的方法…………………………) } }
-
this(代替是当前调用方法属性时的那个对象,不一定是当前类的对象)
-
this和super使用
-
this和super都是指代词,代替的是对象
-
this代替的是当前执行方法是的那个对象,不一定是当前类的,就new出来这个对象的时候才是代替的this
-
super代替的是当前执行方法时的对象的父类对象Animal中sleep()中要调用自己eat()你就只能使用super了因为在类加载模板中先创建的Person类
-
都能调用一般属性和一般方法
-
可以放置在类成员的任意(属性 方法 构造 块)
- 注意调用一般方法的时候可以来会相互调用(写法 编译好用)执行可能产生问题(StakOverflowError)
-
可以调用构造方法(放在构造方法的第一行)
-
this和super在构造方法中调用另一个类的构造方法不能同时出现在第一行
-
构造方法之间不能来回调用(编译不好用)
-
-
-
代码演示
//Animal类 public class Animal{ //Animal的构造方法 public void Animal(){ System.out.printnl("Animal的构造方法…………………………"); } public void eat(){ System.out.println("动物吃饭的方法………………………………"); } public void sleep(){ //this 代替是当前调用方法时的那个对象 不一定是当前类的对象 //如果一定要调用Animal eat() 可以使用super() this.eat();//Animl eat() / Person eat() System.out.println("动物的睡觉方法………………………………"); } } //Person类 public class Person{ public void Person(){ System.out.print("Person的构造方法………………………………"); } //重写父类当中的eat方法 public void eat(){ System.out.println("Person吃饭的方法,讲究色香味俱全"); } //好好学习方法 public void study(){ System.out.println("Good Good study day day up"); } } //程序入口类 public class RunMain(){ public static void main(String [] args){ //加载类的模板的过程 //Person -- Animal -- Object Person person = new Person(); person.sleep();//从Animal类中 } }
-
-
Object是所有类的父类,Object没有父类啦啦,在看hashCode源码的时候看到了native特征符代表调用了底层C++语言方法
- 代码演示
//程序的入口类 public class Test { public static void main(String[] args) { Person person = new Person(); //person继承Obejct类 person.equals();//比较两个对象的内容是否一致 Object默认效果用来比较地址可以重写 ==可以比较基本类型(比较值)可以比较引用类型(比较地址) person.hashCode();//将对象在内存中的地址经过计算得到一个int整数 Object源码public native int hasCode();它不是抽象方法而是底层调用了C++语言帮程序做事 /* 打印输出时将一个对象,变成字符串 打印的变量 返回 十六进制 toString()方法三目运算符 (obj == null) ? "null" : obj.toString(); this.getClass().getName() + "@" + Integer.toHexString(this.hashCode()); 相当于if(a>b){ true }else{ flase } */ person.toString(); person.getClass();//获取对象映射(反射) person.notify();//线程唤醒 person.notifyAll();//唤醒所有 person.wait();//线程进入挂起等待状态 存在重载 finalize();//权限修饰符是Protected 在对象被垃圾回收的时候 默认调用执行的方法 final finally finalize区别 clone();//权限修饰是Protected 为了克隆 git clone } }
方法重写Override和方法重载overload
方法重写override 方法重载overload 类 产生两个继承关系的类 一类中的一组方法 权限 子类可以大于等于父类 没有要求 特征符 final static abstract 没有要求 返回值 子类可以小于等于父类(多态) 没有要求 名字 子类与父类一致 一个类中的好多方法名必须一致 参数 子类与父类一致 每个方法的参数必须不一致(个数 类型 顺序) 异常 运行时 编译时 没有要求 方法体 子类的方法应该于父类不一致 每一个重载的方法 执行过程不一致
-
补充一下类重写类之间满足条件
-
重写必须需求
- 子类必须重写父类的方法
否则不存在重写
- 子类必须重写父类的方法
-
修饰符注意
-
父类方法是final时子类不能重写
-
父类方法是static子类不存在重写
-
父类方法是abstract子类必须重写
-
子类是具体必须重写,否则子类是抽象类 可以不重写
-
-
异常注意
-
如果父类方法抛出运行时异常子类不予理会
-
如果父类方法抛出编译时异常子类抛出异常的个数少于等于父类
-
子类抛出异常的类型小于等于父类
-
-