首页 > 代码库 > 13.继承

13.继承

1.继承

关键字:extends

class Father{
    public int num1=10;
    private int num2=20;
    protected int num3=30;

    public Father(int num1,int num2,int num3){
        this.num1=num1;
        this.num2=num2;
        this.num3=num3;
    }

    public Father(){
        System.out.println("Father");
    }

    @Override
    public String toString() {
        return String.format("%d %d %d",num1,num2,num3);
    }
}

class Son extends Father{
    public Son(int num1,int num2,int num3){
        super(num1,num2,num3);
    }

    @Override
    public String toString() {
        return super.toString();
    }

  public static void main(String[] args){
    System.out.println(new Son(1,2,3));
  } }//输出 1 2 3

重点

a.创建子类对象的时候会调用父类的构造函数,如果是无参数的构造函数,会自动的调用,不用写super()

b.Father father=new Son();//Son的实例但是进行了向上转型,father引用可以调用Father类中的函数,以及子类中被重写的函数(多态),但是父类的引用是不能调用子类的属性的,因为多态只针对方法不针对属性

例子:

public class Main {
    public static void main(String[] args){
        /*创建子类对象的时候会调用子类的构造函数*/
        Son son=new Son();

        /*输出num1的值*/
        Father father=new Son();
        System.out.println(father.num1);

        /*调用函数f()*/
        father.f();
    }
}

class Father{
    public int num1=10;
    public Father(){
        System.out.println("Constructor of Father");
    }

    public void f(){
        System.out.println("Father‘s f()");
    }
}

class  Son extends Father{
    public int num1=20;
    public Son(){
        System.out.println("Constructor of Son");
    }

    @Override
    public void f(){
        System.out.println("Son‘s f()");
    }
}//输出:

Constructor of Father
Constructor of Son
Constructor of Father
Constructor of Son
10
Son‘s f()

 覆盖与重载

  • 注意:重载与覆盖的区别
  • 重载(函数名称一样、参数的类型或者个不一致、与返回值无关)  
  • 覆盖(必须是有继承关系的两个类之间,函数的访问权限,函数名称,参数的类型个数都必须一致)
  • @Override之后必须是覆盖而不能是重载--经常用在实现接口的函数的时候

 Public、private、protected关键字

class A{
      public String name=new String(“Tom”);
      protected String school=new String(“SouthEast University”);
      private String sex=new String(“M”);
}
  • public关键字不做过多的解释,通过指向A对象的引用,可以访问name属性
  • private关键字,在A的类作用域之外,不能直接使用sex熟悉
  • protected关键字
      • 1.同包内protected与public相同
      • 2.不同包内,2.1不是A的子类与private相同,
          •  2.2是A的子类与public相同(只能在子类的作用域内),这就是为什么下边的代码为什么不能执行的原因
            public class Test{
                    public static void main(String[] args){
                          Object obj=new Object();
                          System.out.println(obj.hashCode()); 
                    } 
            }    
            //解释
            按道理所有的类都是Object的子类,hahCode是protected函数,也就是说对于Object的子类,都可以执行hashCode()函数,但是必须在子类包中,这里就是Object所在的包中
            这样写就是没问题的
            @Override
            public int hashCode(){
              return super.hashCode();
            }
  • 省去包修饰符是包访问权限

关键字:final

作用如下

  • 修饰属性,表示编译器常量
      • final int a=9;//被初始化之后就不能改变--一般常量
      • static final int A=9;//静态常量--类的常量
    • 备注:Java中的final变量在定义的时候可以不进行初始化,但是初始化之后就不能修改常量的值
        • eg:
        • final int m;
        • m=30;
        • m=20;//Wrong  
  • 修饰对象和数组引用,表示引用不能改变“指向”
      • final int[] a=new int[]{1,2,3};
      • a[0]=1000;//可以改变数组的值
      • a=new int [20];//Wrong 不能改变a的引用
  • 修饰方法,表示函数不能被重写(覆盖)
  • private 其实就是隐式的final函数,但是本质还是不一样的,只能说peivate 函数是有final关键字的
      • 1.final 函数,子类中不能添加同名同参数的函数
      • 2.private函数,子类中可以添加同名同参数的函数,但是这个不是重写,只是添加了自己的同名函数,与父类无关--------强烈建议避免这样写
      •  class Instrument {
            private void display(){System.out.println("Instrument‘s display");}//无法被覆盖
        }
        
        public class Wind extends Instrument{
            private void display(){System.out.println("Wind‘s display");}//并不是覆盖父类的函数,而是添加自己的函数
            public static void main(String[] args){
                Instrument instrument=new Wind();//向上转型为父类的对象同时丢失父类的private方法
                instrument.display();//Wrong
            }
        }
  • 修饰类,表示类不能被继承

    

13.继承