【面向对象-继承】
关键字:extends
举例:
将学生和工人的共性描述提取出来,单独进行描述
只要让学生和工人单独描述的这个类有关系,就可以了
继承
1,提高代码的复用性
2,让类与类之间产生关系,有了关系,才有了多态的特性。
注意:
不要为了获取其他类的功能,简化代码而继承
必须是类与类之间有所属关系才可以继承,所属关系,is a 谁是谁中的一员/一种。
java语言中: java只支持单继承,不支持多继承
因为多继承容易带来安全隐患。
当多个父类中定义了相同功能,当功能内容不同时,子类不确定要运行那一个。
但是java保留了这种机制,并用另外一种体现形式来完成表示,叫:多实现。
java支持多层继承。 个人理解树根儿形
【使用功能。】
如何使用一个继承体系中的功能呢,
想要使用提示,先查阅体系中父类的描述,因为父类中定义的是该体系中的共性功能
通过了解共性功能,就可以知道该体系的基本功能。
那么,这个体系已经基本使用了。
在具体调用时,要创建最子类的对象,为什么呢
1,因为父类有可能不能创建对象
2,创建子类对象,可以使用更多的功能,包括基本的,也包括特有的。
简单一句话:【查阅父类功能,创建子类使用功能】。
聚合,组合,聚集
this 是当前对象
super 父类
--------------------------------------------------------------------------------------------------------
【例子1】
package DayXuexi;
/*
* 子父类出现后,类成员的特点:
* 类中成员:
* 1,变量
* 2,函数
* 3,构造函数
*
* 【1,变量】
* 如果子类中出现非私有的同名变量时
* 子类要访问本类中的变量,用this
* 子类要访问父类中的同名变量,用super
* this是当前对象的引用,super 则是父类对象的引用
*
* 【2,函数】
* 当子类出现和父类一模一样的函数时
* 当子类对象调用该函数,会运行子类函数的内容
* 如同父类的函数被覆盖一样
*
* 当子类继承了父类,沿袭了父类的功能到子类中,
* 但是,子类虽具备该功能,功能的内容却和父类不一致
* 这时没有必要定义新功能,而使用覆盖特性保留父类的功能定义,并重写功能内容
* [千万别修改源码]重写
*
* 这种情况是函数的另一个特性:重写(覆盖)
* 【重写】注意事项;
* 1,写覆盖的时候,必须保证子类权限要大于等于父类权限,否则编译失败。
* 2,静态只能覆盖静态。 不能覆盖非静态
* 3,重载完全不同重写
* 重载:只看同名函数的参数列表
* 重写:子父类方法要一模一样
*
* 权限:学过3种:public private 和什么都不写默认权限
*
* 【3,构造函数】
* 构造函数是不能覆盖的,应为覆盖一定要子父类方法【一模一样】的
* 在对子类对象进行初始化时,父类的构造函数也会运行,
* 是因为子类的构造函数默认第一行有一条隐式的语句叫 superv();
* super();会访问父类中的空参数的构造函数,而且子类中的所有的构造函数默认第一行都是super();
*
* 子类中,不论调用那一个构造函数,都会默认调用父类的空参数构造函数,因为super();默认在第一行。
*
* 【】
* 为什么子类一定要访问父类中的构造函数 [子类必然访问父类主函数]
* 因为父类中的数据子类可以直接获取,所以子类对象建立时,需要查看父类是如何对这些数据进行初始化的。
* 所以子类在对象初始化时,要先访问一下父类中的构造函数
* 如果要访问父类中指定的构造函数,可以通过手动定义super语句来指定。这个时候就的把super定义出来
* 【切记】super(); 一定要放在【子类构造函数】的【第一行】。
* 比如 【001】
*
*
* 结论:
* 【子类的实例化过程】
* 子类的所有的构造函数,默认都会访问父类中的空参数构造函数。
* 因为子类每一个的构造函数内都有一句隐式super();
*
* 当父类中没有空参数的构造函数时,子类必须手动通过super 或者this 语句形式来指定要访问的构造函数
* 当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,
* 子类中至少有一个构造函数会访问父类中的构造函数
*
* [父类中也有super语句]
*
*
* 没有条件的递归就是死循环
*/
【例子1】
class Fu{
//int num1=4;
int num=4;
Fu(){
System.out.println("Fu run");
}
Fu(int x){
System.out.println("Fu ....");
}
}
class Zi extends Fu{
//int num2=5;
int num=5;
Zi(){
//super();子类所有的构造函数默认第一行都是该语句
System.out.println("Zi run");
}
Zi(int x){
//super(3); 【001】通过这句话,指定访问父类中的带参数构造函数
System.out.println("Zi.....");
}
void show(){
System.out.println(this.num);
System.out.println(super.num);
//this是当前对象super 则是父类的意思。
}
}
public class Dome_extends {
public static void main(String []args){
//Zi z=new Zi();
//System.out.println(z.num1+"...."+z.num2);
//System.out.println(z.num+"...."+z.num);
//z.show();
System.out.println("\n");
//这个时候运行,发现父类和子类的构造函数都运行了,因为//super();子类所有的构造函数默认第一行都是该语句
// 再来一个
Zi z1=new Zi(99);
//这个时候运行,调用了带参数的构造函数,然后父类和 子类的 带参数的 构造函数】都运行了
//现在我们试试给父类添加一个带参数的构造函数试试,发现不会调用到它。
}
}
【【例子2】】
/*
* 练习:
* 加入我们在开发一个系统时,需要对员工进行建模,员工包含3个属性
* 姓名,工号,工资,经理也是员工,除了含有员工的属性外,
* 另外还有一个奖金属性,请使用继承的思想设计出员工类,和经理类,
* 要求类中提供必要的方法进行属性访问。
*
* 我的思路:
* 既然经理也属于员工,那么普通员工和经理就应该继承与同一个类。
* 姓名,工号,工资是不确定的,所以是一般成员变量,
* 假设奖金是固定的,那么可以用final修饰。
*
* 试着做一次然后在看来时教学视频:
*
* 老师的思路:
*
* 员工类
* 经理类继承了员工,并有自己特有的bonus.
*
* 一般方法被abstract抽象,那么这个类也必须用abstract抽象,否则编译不过。
*/
public class Demo_Lianxi {
public static void main(String []args){
/*
genSatff gs=new genSatff();
gs.setName("dddd");
gs.setNumber("5424");
gs.setMoney(6000);
gs.show();
manager ma=new manager();
ma.setName("jinli");
ma.setNumber("0001");
ma.setMoney(20000);
ma.show();
*/
}
}
//yuangong
abstract class Employee{
private String name;
private String id;
private double pay;
//用构造函数来传递名字
Employee(String name, String id,double pay){
this.name=name;
this.id=id;
this.pay=pay;
}
//工作的方法,因为工作是不具体的,所有就是抽象的:
abstract void work();
}
class pro extends Employee{
pro(String name,String id, int pay){
super(name,id,pay);
}
public void work() {
System.out.println("pro");
}
//关于复写这个方法的时候,有些困惑,为什么我手打代码报错,生成的却不报错了。
}
class Manager1 extends Employee{
private int bonus;
Manager1(String name, String id,double pay,int bonus){
super(name,id,pay); //指定调用父类构造函数
//因为父类中已经定义了带参的构造函数,所以子类创建的时候如果不指定调用父类构造函数,是会提示出错的。
this.bonus=bonus;
}
public void work() {
System.out.println("manager");
}
}
/*【【【误区】】】
* 昨天走入一个误区::
* 以前知道想要读写private里的变量,要用到get、set访问器。
* 在这里,老师直接在父类构造函数中传递了private,子类只需要复写相同构造函数即可实现get、set访问器功能
* 并且代码量相对较少,意思就是说,构造函数可以取代或者使用更多?我不知道是不是走如了什么误区,
* 求指点啊。
* 【事实证明】,【是两码事】
* 忘记一点:【构造函数用于初始化】,而【get、set访问器】。可以多次进行读和写
*
* 【】
* 所以上面和下面的代码相结合就应该是最正确的代码了。
* 上面是初始化几种情况的数据的默认值
* 下面是提供访问器,对数据进行读写
*/
//自己的思路
//员工类 【ser fu】
class satff{
private String name;
private String number;
private int money;
private final int J_MONEY=1200;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public String getNumber(){
return number;
}
public void setNumber(String number){
this.number=number;
}
public int getMoney(){
return money;
}
public void setMoney( int money){
this.money=money;
}
public void show(){
System.out.println("name:"+name+"..number:"+number+"..money:"+money+"..jin:"+J_MONEY);
}
}
//普通员工
class genSatff extends satff {
}
//经理
class manager extends satff{
}
---------- android培训、 java培训、期待与您交流!----------
黑马官网: http://edu.csdn.net/heima