黑马程序员_Java基础[12]_继承

---------- android培训 java培训、期待与您交流! ----------


【面向对象-继承】
关键字: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值