第十三节(super关键字、final关键字、抽象类))

super 关键字的作用:

  调用父类的构造方法

  调用父类的成员方法

需要注意:super 只能应用在成员方法和构造方法中,不能应用在静态方法中(和 this 是一

样的) ,如果在构造方法中使用必须放在第一行

为什么会有 super 关键字?

 因为子类必须要调用父类的构造方法,先把父类构造完成,因为子类依赖于父类,没有父,也就没有子有时需要在子类中

 显示的调用父类的成员方法


那么我们以前为什么没有看到 super,而且我们也有继承,如:Student 继承了 Person ?

因为子类中我们没有显示的调用构造方法,那么他会默认调用父类的无参构造方法,此种情况下如果父类中没有无参构造方法

那么编译时将会失败注意构造方法不存在覆盖的概念,构造方法可以重
public class Person{

    // 姓名
    private String name;
    // 性别
    private boolean sex;
    // 年龄
    private int age; 
    
    
    public Person(){
        System.out.println("--------Person--------");    
    }
    
    public Person(String name,int age){
        this.name = name;
        this.age = age;    
        System.out.println("-------------Person super-------------");
    }
    
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;    
    }
    
    public void setSex(boolean sex){
        this.sex = sex;
    }
    public boolean getSex(){
        return sex;    
    }
    
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return age;    
    }
    
}

/*
    super关键字 用在构造方法中
    
        语法:super(实参);
    
        作用:通过子类的构造方法调用父类的构造
        语法规则:
            一个构造方法第一行 如果没有this(...); 也没有显示去调用super();
            系统会默认调用super();
        
        注意:super(...); 的调用 只能放在构造方法的第一行
        super(..) 和 this(...); 是不能共存;
        
        
        通过子类的构造方法去调用父类的构造方法
        作用:给当前子类对象中的父类特征赋值
        
        
*/
public class Student extends Person{
    
    // 班级号
    private int classId;
    
    // 学科
    private String subject;
    
    // 是否有女朋友
    private boolean girlFriend;
    
    
    public Student(){
        super();
        this.subject = "ming";
        //System.out.println(this);
        //super();
        // 编译错误,必须将super放到构造函数的第一句
        // 必须创建父类,才创建子类
    
        System.out.println("-------------Student-------------");
    }
    
    public Student(String name,int age){
        // 手动调用带参数的构造函数
        super(name,age);
        
        System.out.println("-------------Student super-------------");
        
    }
    
    
    
    public void setClassId(int classId){
        this.classId = classId;
    }
    public int getClassId(){
        return classId;    
    }
    
    public void setSubject(String subject){
        this.subject = subject;
    }
    public String getSubject(){
        return subject;    
    }
    
    public void setGirlFriend(boolean girlFriend){
        this.girlFriend = girlFriend;
    }
    public boolean getGirlFriend(){
        return girlFriend;    
    }        
    
}

/*
    

*/
public class SuperTest01{


    
    // Java的入口
    public static void main(String[] args){
        
        Person stu = new Student();
        
        Person stu1 = new Student("ming",40);    
        
        
    }


}
输出结果:
--------Person--------
-------------Student-------------
-------------Person super-------------
-------------Student super-------------
final 表示不可改变的含义
  采用 final 修饰的类不能被继承

  采用 final 修饰的方法不能被覆盖

  采用 final 修饰的变量不能被修改

  final 修饰的变量必须显示初始化s 如果修饰的引用, 那么这个引用只能指向一个对象, 也就是说这个引用不能再次赋

值,但被指向的对象是可以修改的


  构造方法不能被 final 修饰

  会影响 JAVA 类的初始化:final 定义的静态常量调用时不会执行 java 的类初始化方法,也就是说不会执行 static 代码块等相关语句,

这是由 java 虚拟机规定的。

/*
    final 修饰
        
        final修饰的方法无法被覆盖的

*/
public class finalTest01{

    
    
}


class Ming{
    
    // final 修饰的局部变量,一旦赋值,不可再改变,允许初始化(第一次赋值)
    public final void  m1(){
        
        final int i;
        // 第一次赋值
        i = 10;
        
        // 第二次赋值
        // i = 100;
        
    }

}

class Keke extends Ming{
//    public void m1(){}
}


/*
    final 修饰的成员变量 必须“显示的”初始化
*/
class Tony{

    // final 修饰的成员变量 必须要手动赋值
     final int age = 30;
     
     
     // final 修饰的成员变量 一般和static联用
     // 常量 .java规范中 要求所有的常量“大写”
     // 常量: 值不可再改变的变量
     public static final double PI = 3.14;

    
    //final int age = 40;
    
    public static void main(String[] args){
        
        Tony t = new Tony();
        
        System.out.println(t.age);
        
    }
    
}

/*
    深入 final
    
        final 修饰的引用类型,该引用不可以再从新指定其他的java对象
        但是 final修饰的引用,该引用指向的对象的属性是可以修改的
    

*/
public class FinalTest02{
    
    public static void main(String[] args){
        
/*        final User u = new User("ming",18);
        
        u.name = "Tony";
        u.age = 38;
*/


/*    编译错误:
        final User u = new User("ming",18);
        u = new User("Tony",38);
;    */    
        
        System.out.println("name: " + u.name );
        System.out.println("age: " + u.age );
        
    }

}


class User{
    
    String name;
    int age;
    
    User(String name,int age){
        this.name = name;
        this.age = age;    
    }
    

}
抽象类的定定义:


  1. 在 java 中采用 abstract 关键字定义的类就是抽象类,采用 abstract 关键字定义的方法就是抽象方法

  2. 抽象的方法只需在抽象类中,提供声明,不需要实现

  3. 如果一个类中含有抽象方法,那么这个类必须定义成抽象类

  4. 如果这个类是抽象的, 那么这个类被子类继承, 抽象方法必须被重写。 如果在子类 中不复写该抽象方法,

    那么必须将此类再次声明为抽象类

  5. 抽象的类是不能实例化的, 就像现实世界中人其实是抽象的, 张三、 李四才是具体的

  6. 抽象类不能被 final 修饰

  7. 抽象方法不能被 final 修饰,因为抽象方法就是被子类实现的

      抽象类中可以包含方法实现, 可以将一些公共的代码放到抽象类中, 另外在抽象类中可以定义一些抽象的方法,

这样就会存在一个约束,而子类必须实现我们定义的方法

/*
    抽象类
        
        1. 定义抽象类 
            class 关键字前边 添加 abstract
        2. 抽象类是不能够被实例化的 
        3. 在抽象类中可以定义 一些子类公共的方法或属性
        4. 抽象方法只在抽象类中,提供声明,不需要实现,起到了一个强制的约束作用,要求子类必须实现
        5. 在抽象类中定义抽象方法:
            
            在方法的修饰符列表中 添加abstract关键字,并且抽象方法应该以“;”结束,不能带有“{}”
            例子:public abstract void printInfo();
            
        6. 抽象类 中不一定有抽象方法,但抽象方法必须在出现在抽象类中
        7. 一个非抽象的类继承抽象类,必须将抽象类中的 方法覆盖(实现,重写)。

*/

public class AbstractTest01{
    
    public static void main(String[] args){
    
    /*     编译错误:抽象类是不能够被实例化的 
        Person p = new Person();
        p.setName("Arry老师");
    */    
        
        // 以下使用时正确的,我们new的是具体的类
/*        Person p1 = new Student();
        p1.setName("keke老师");
        
        System.out.println("姓名:"+p1.getName());
*/

        Person p1 =  new Student();
        Person p2 =  new Teacher();
        
        p1.setName("ming");
        p1.printInfo();
        System.out.println("姓名:"+p1.getName());
        
    }

}


abstract class Person{
    
    private String name;
    
    //Person(){}
        
    // 使用abstract 定义抽象方法
    // 如果一个类中含有抽象方法,那么这个类必须定义成抽象
   // 如果类是一个抽象的,并不要求具有抽象的方法
    public abstract void printInfo();
    
    
    // 此方法各个子类都可以使用
    public void commonMethod(){
        System.out.println("----------commonMethod---------");    
    }
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    
}


class Student extends Person{
    
    // 强制性实现抽象方法
    public void printInfo(){
        System.out.println("----Student.printInfo()---");    
    }
    
}

class Teacher extends Person{

    // 强制性实现抽象方法
    public void printInfo(){
        System.out.println("----Teacher.printInfo()---");    
    }

}
/*
输出:
---Student.printInfo()---

姓名:ming
*/

 

 

 

posted @ 2015-01-16 21:51  哥的笑百度不到  阅读(264)  评论(0编辑  收藏  举报