1.继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
2.extands的意思是“扩展”,子类是父类的扩展
3.JAVA中类只有单继承,没有多继承 (一个类的直接父类只能有一个)
4.继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等
5.继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
6.子类和父类之间,从意义上讲应该具有"is a"的关系
7.Java语言可以多级继承
8.一个子类的直接父类是唯一的,但是一个父类可以拥有很多个子类
9.在Java中,所有的类都默认直接或者间接继承Object类
代码①
Person类(父类)
public class Person {
public int money=10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
Student类(子类)
public class Student extends Person {
}
main方法
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.money);
}
运行结果:
说了一句话
1000000000
代码分析:
1.Student类中并没有语句,但是Student类继承了Person类,也就继承了Person中的全部方法,所以可以调用成功
2.即子类继承了父类,就会拥有父类的全部方法
代码②
当把money改为私有的时候,会出现报错的情况
在这个时候,需要在Person中加入money的get/set方法,student才可以引用
Person类(父类)
public class Person {
public int money=10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
Student类(子类)
public class Student extends Person {
}
main方法
public static void main(String[] args) {
Student student = new Student();
student.say();
student.setMoney(10_0000_0000);
System.out.println(student.getMoney());
}
运行结果:
说了一句话
1000000000
代码③
直接通过子类对象访问成员变量:
等号左边是谁.就优先用谁,没有则向上找
间接通过成员方法访问成员变量:
方法属于谁,就优先用谁,没有则向上找
Fu类
public class Fu {
int numFu=10;
int num=200;
public void methodFu(){
//num使用的是本类当中的,不会找子类的
System.out.println(num);
}
}
Zi类
public class Zi extends Fu{
int numZi=20;
int num=100;
public void methodZi(){
//本类中有num,所以使用的是本类中的num
System.out.println(num);
}
}
main方法
public static void main(String[] args) {
Fu fu = new Fu();
System.out.println(fu.numFu);//10
System.out.println("=========================");
Zi zi = new Zi();
System.out.println(zi.numFu);//10
System.out.println(zi.numZi);//20
System.out.println("=========================");
System.out.println(zi.num);//100
System.out.println("=========================");
zi.methodZi();//100
zi.methodFu();//200
fu.methodFu();//200
}
代码④
在父子类的继承关系中,创建子类对象,访问成员方法的规则
创建的对象是谁,就优先用谁,如果没有则向上找
注意:
无论是成员方法还是成员变量,如果没有就是向上找,绝对不会向下找子类的
Fu类
public class Fu {
public void methodFu(){
System.out.println("父类方法执行");
}
public void method(){
System.out.println("父类重名方法执行");
}
}
Zi类
public class Zi extends Fu{
public void methodZi(){
System.out.println("子类方法执行");
}
public void method(){
System.out.println("子类重名方法执行");
}
}
main方法
public static void main(String[] args) {
Zi zi = new Zi();
zi.methodZi();//子类方法执行
zi.methodFu();//父类方法执行
zi.method();//子类重名方法执行
}
代码⑤ 设计原则
对于已经投入使用的类,尽量不要修改,推荐定义一个新的类,来重复利用其中共性内容,并且添加改动新内容
Phone类(父类)
//老款手机
public class Phone {
public void call(){
System.out.println("打电话");
}
public void send(){
System.out.println("发短信");
}
public void show(){
System.out.println("显示号码");
}
}
NewPhone类(子类)
//新手机,老手机作为父类
public class NewPhone extends Phone{
@Override
public void show() {
super.show();//把父类的show方法拿过来重复利用
//自己子类再来添加更多内容
System.out.println("显示姓名");
System.out.println("显示头像");
}
}
main方法
public static void main(String[] args) {
Phone phone = new Phone();
phone.call();
phone.show();
phone.send();
System.out.println("=============================");
NewPhone newPhone = new NewPhone();
newPhone.call();
newPhone.send();
newPhone.show();
}
运行结果:
打电话
显示号码
发短信
=============================
打电话
发短信
显示号码
显示姓名
显示头像
代码⑥ 关于super()
通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
Person类(父类)
public class Person {
protected String name="Sherlock";//受保护的属性
//输出的方法
public void print(){
System.out.println("person");
}
}
Student类(子类)
public class Student extends Person {
private String name="Jone";
//输出的方法
public void print(){
System.out.println("student");
}
//测试输出的方法
public void test1(){
print();//student
this.print();//student
super.print();//person
}
public void test(String name){
System.out.println(name);//main方法中输入的名字
System.out.println(this.name);//Jone,this.name:当前类的东西
System.out.println(super.name);//Sherlock,调用父类的name
}
}
main方法
public static void main(String[] args) {
Student student = new Student();
student.test("夏洛克");
System.out.println("==============");
student.test1();
}
运行结果:
夏洛克
Jone
Sherlock
==============
student
student
person
补充① this
super用来访问父类内容,this关键字用来访问子类内容
1.在本类成员方法中,访问本类成员变量
2.在本类成员方法中,访问本类另一个成员方法
3.在本类的构造方法中,访问本类的另一个构造方法
注:
this(…)调用也要注意,必须是构造方法的第一个,也是唯一一个
Fu类
public class Fu {
int num=30;
}
Zi类
public class Zi extends Fu{
int num=20;
public Zi() {
this(6);//本类的无参构造,调用本类的有参构造
}
public Zi(int n){
}
public void showNum(){
int num=10;
System.out.println(num);//局部变量
System.out.println(this.num);//本类中的成员变量
System.out.println(super.num);//父类中的成员变量
}
public void methodA(){
System.out.println("AAA");
}
public void methodB(){
this.methodA();
System.out.println("BBB");
}
}
补充② super()
当把Person类中的print方法改成私有private的时候,在student中用super也无法访问
这是因为私有的东西无法继承
补充③ super
Person类(父类)
public class Person {
protected String name="Sherlock";//受保护的属性
//父类构造器
public Person() {
System.out.println("无参构造执行");
}
}
Student类(子类)
public class Student extends Person {
//子类构造器
public Student(){
System.out.println("student的无参构造执行了");
}
}
main方法
public static void main(String[] args) {
Student student = new Student();
}
运行结果:
无参构造执行
student的无参构造执行了
代码分析:
子类中的构造器中,有super();的默认代码,会调用父类的构造器
如下所示
public class Student extends Person {
//子类构造器
//隐藏代码 调用了父类的无参构造
public Student(){
//super();隐藏代码 调用了父类的无参构造
super();//调用父类的构造器,必须要在子类构造器的第一行,这一行代码默认就会有,自己不用写出来
System.out.println("student的无参构造执行了");
}
补充④ super
子类构造可以通过super关键字来调用父类重载构造
Fu类
public class Fu {
public Fu() {
}
public Fu(int num) {
System.out.println("父类构造方法!");
}
}
Zi类
public class Zi extends Fu{
public Zi() {
super(10);//子类构造可以通过super关键字来调用父类重载构造
System.out.println("子类构造方法!");
}
}
super总结
super注意点:
1.super调用父类的构造方法,只能有一个super,且必须在构造方法的第一个,即一定是先调用父类构造.后执行子类构造
2.super必须只能出现在子类的方法或者构造方法中
3.super和this不能同时调用构造方法,即super和this在构造方法中不能同时使用
super vs this:
1.代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
2.前提:
this:没有继承也可以使用
super:只能在继承情况下使用
3.构造方法:
this:默认调用本类的构造
super:默认调用父类的构造