继承2

 继承由来是什么:当我们在定义若干个类的时候,发现某一些类中具有相同的属性和行为,那么,我们就可以将这些相同的部分进行抽取,独立生成另外一个类,那么这个生成出来 的类我们称之为是父类,其他的被抽取内容的类称之为子类, 子类与父类之间就是所谓的继承关系 用 extends来表示

public class People {
  String name;
  int age;
  void eat() {	  
  }
}
class Student extends People{
	void study() {		
	}
}
class Worker extends People{
	void working() {		
	}
}

Student和worker继承了People的属性和方法,如果这属性和方法是私有(private)修饰的,那就无法继承

 那么在现实生活中,父与子之间的一对多 还是多对多的关系?

 在Java当中 继承是单继承(一个子类只能有一个父类,但是一个父类可以有若干个子类),当然,在C++中,继承是多继承的,不太符合实际的社会问题,所以Java更加符合现实编程, (不代表Java当中就没有多继承的时候!如果是类与类之间 必须是单继承;如果是接口与接口之间,可以是多继承), 既然有了继承,那么在Java当中就有了继承体系,我们常用的继承体系都有异常体系,集合体系,IO体系, 网络体系,多线程体系等,在Java继承体系当中,所有类的最终父类都是Object

如果我们在定义一个类的时候,没有显著声明父类的时候,那么该类的父类默认是Object,注意一点:在分析设计继承的时候 一定要符合社会常识问题,子类和父类之间必须是 is a 关系,子类必须父类的一种,同一系列的,she is a Girl  ; he is a boy ; he is a ladyboy ; 旺财 is a Dog,所以,千万不要为了获取某一个类的功能而把这个类叫爸爸

 子父类中成员变量/静态变量的特点:
        如果只有子类有且非私有 那么就调用子类的
        如果只有父类有且非私有 那么就调用父类的
        如果子父类都有且非私有 那么就调用子类的
        (成员变量之间 是不存在重写关系的!!!)
        子类.属性 顺序:子类对象成员->子类静态->父类成员->父类静态
        子类成员函数在内部调用变量时 局部变量->子类对象成员->子类静态->父类成员->父类静态

package test2;
class gradfather{
	int num4=200;
}
class Person extends gradfather{
	int num1=10;
	static int num2=40;
	static int num3=50;
}
class Student extends Person{
	int num1=20;
	static int  num2=30;
	void show() {
		System.out.println(num1+","+num2+","+num3);//20,30,50
		//局部变量和成员变量重名就用this关键字来区分
		//用super来区分子类和父类的成员变量或局部变量
		//结果就是10,40,50
    System.out.println(super.num1+","+super.num2+","+num3);
        //结果就是200,前面没有找到就去找它爷的num4
    System.out.println(num4);
	}
	public static void main(String[] args) {
		Student s=new Student();
		s.show();
	}
}

内存图

 

构造函数刚一弹栈,就把0x123这个地址给了t 

 现象:子类的构造函数在调用运行的时候 先执行父类的构造函数

package test2;
class Person{
	Person(){
		System.out.println("fu constructor");
	}
	int num1=10;
	static int num2=40;
	static int num3=50;
}
class Student extends Person{
	Student(){
		System.out.println("zi constructor");
	}
	int num1=20;
	static int  num2=30;
	void show() {
		System.out.println(num1+","+num2+","+num3);//20,30,50
		//局部变量和成员变量重名就用this关键字来区分
		//用super来区分子类和父类的成员变量或局部变量
		//结果就是10,40,50
    System.out.println(super.num1+","+super.num2+","+num3);
	}       
	public static void main(String[] args) {
		Student s=new Student();
		s.show();
	}
}

执行的结果就是:
 

 在子类的构造函数当中,有一句默认的super(...)隐藏了,而且这句代码必须是在第一行, 对super的调用必须是构造器中的第一个,为什么?道理很简单 儿子向老爸要钱,那么老爸是不是得先准备一下钱, 既然子类继承自父类 那么必然会继承到父类当中的一些数据,所以,在子类构造函数之中,必须先让父类把这些数据进行一些初始化才能继承给子类, 注意:父类的构造函数被调用,但不代表父类就被创建对象了!, 所以this是当前对象的引用,而super不是父类对象的引用,而是父类空间的引用, 并且注意super(...) 如果父类没有默认无参构造函数 那么子类构造函数中super()失效了, 所以在调用父类构造函数时,一定要注意父类构造函数的参数情况!适时修改super(...),this(...)是当前类中,本类构造函数调用本类构造函数的方式, super(...)是本类构造函数调用父类构造函数的方式,都必须在第一行 那么这两冲突不?, 如果本类构造函数当中不存在调用关系 那么每一个本类构造函数第一句都是super(...),如果本类构造函数当中存在调用关系,那么最后被调用的那个构造函数第一句绝对是super(...),this(...)的调用是单向的还是递归的?是单向的,那么最后被调用的第一句绝对就是super(...)

 子父类中成员函数的特点:
        如果只有子类有且非私有 那么就调用子类的
        如果只有父类有且非私有 那么就调用父类的
        如果子父类都有且非私有 那么就调用子类的(函数重写)

  函数重写:在子父类中,同名函数

函数有什么组成:函数声明(权限 类型 返回值类型 函数名 参数列表)+函数体({}里面的内容)

重写的意义在于哪?在于子类继承了父类的函数声明(功能),但是子类可以将该函数的具体实现进行优化或更改,  1.保留父类的功能声明,子类可以进一步优化     2.保留父类的功能声明,子类可以重新定义

 重写当中应该注意到的一些细节:
    1.函数重名 但是参数列表不同 不构成重写关系
    2.函数重名 参数列表相同 构成重写关系 返回值类型也必须是一样的
    3.子类重写父类函数时,权限>=父类权限
    4.当然 如果父类函数权限为private 子类压根就继承不到 何谈重写

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值