构造函数&继承&重写&多态

构造函数

class Student{
    String stuName;
    public Student(){
        System.out.println("无参构造函数");
    }
    public Student(String name){
        System.out.println("带参的构造函数");
        this.stuName = name;
        //System.out.println("name ="+);
    }

}

class  Demo{
    public static void main(String[] args){
        System.out.println("无参");
        //创建(实例化)无参的对象调用类中的无参构造函数
        Student stu1 = new Student();
        System.out.println("----------------");
        System.out.println("带参构造函数");
        //创建(实例化)带参的对象调用类中的含参构造函数
        Student stu2 = new Student("刘德华");
        System.out.println("name = "+stu2.stuName);
    }
}

这里写图片描述

构造函数的私有化

作用

  • 像这种只提供功能性方法的类,包含的全部都是static的方法,这样的类一般不需要实例化,通过类名就可以访问成员属性,所以,可以将此类的构造函数设为私有的,外部不能实例化;
class MyMath{
    private MyMath(){
        System.out.println("私有化构造函数");//私有的不能实例化,同时也不会运行到这一步
    }
    public static int getMax(int a , int b){
        return a > b ? a : b;
    }
    public static int getMin(int a , int b){
        return a < b ? a : b;
    }
}
class Demo{
    public static void main(String[] args){
        //MyMath m = new MyMath();编译错误,私有的构造函数不能实例化
        System.out.println(MyMath.getMax(10,20));
        System.out.println(MyMath.getMin(10,20));
    }
}
  • 例模式:在我们的整个应用程序运行期间,只需要一个某个类的对象,这时,我们可以将此类设计为”单例模式”,整个应用程序运行期间,只有一个对象存在
    步骤:
    1.将此类的构造器设为私有;
    2.提供一个私有的属性,这个属性是这个类的一个对象;
    3.提供一个公有的静态方法,返回这个私有属性
class Student2{
    //私有静态属性:
    //作用:提供给内部的静态的方法访问
    private static Student2 stuObj = new Student2();
    private Student2(){
    }
    public static Student2 getStudentInstance(){
        return stuObj;
    }
}

继承

  1. 类中出现重复的属性定义
  2. 继承之后,子类将拥有父类中允许被继承的成员(属性和方法)(父类中的私有private属性、方法不能被子类继承)
  3. 代码复用
  4. 继承是一种可以访问的权限,并不是真正拥有父类的成员属性和成员方法
  5. java不支持多继承,但是支持多级继承
    多继承
    class SubDemo extends Demo{} //ok
    class SubDemo extends Demo1,Demo2…//error
    多级继承
    class A{}
    class B extends A{}
    class C extends B{}
class A{//父类
    String name;
    char sex;
    int age;
    public void show(){
        System.out.println("我叫:" + name + ",性别:" + sex + ",年龄:" + age);
    }
}

class C extends A{//子类
    String stuNo;//学员编号
}

class Demo{
    public static void main(String[] args){
        C stu = new C();
        stu.stuNo = "00001";
        stu.name = "张学友";
        stu.sex = '男';
        stu.age = 30;
        stu.show();
    //  System.out.println(stu.name + "," + stu.sex + " , " + stu.age);
    }
}

子类的实例化过程

这里写图片描述

class Personnel{
    private int num = 10;//父类中私有的东西,不能被继承
    Personnel(){
        System.out.println("父类构造函数");
    }
    String name= "Personnel";
    int age;
}
class Student extends Personnel{
    private int num = 20;//子类中也定义一个同父类中相同的私有的变量。被认为是子类自己的成员变量
    Student(){
    /*
     *子类中所有的构造函数默认都会访问父类中空参数的构造函数,
     *因为每一个构造函数的第一行都有一条默认的语句super();
    */
        super();
        System.out.println("子类构造函数");
    }
    String stuNo;
    String name = "Student";
    public void show(){
        System.out.println("name = " + name);//Student
        System.out.println("父类的name = " + super.name);//Personnel
        System.out.println("试图调用父类中私有的num变量 = " + num);//如果子类也有num,将访问子类的num
    }
}
class Demo 
{
    public static void main(String[] args) 
    {
        Student stu = new Student();
        stu.show();
    }
}

继承时super和this关键字的使用

  • this关键字代表本类对象的引用
  • super关键字代表父类内存空间的标识,只能在子类中调用父类对象时使用
class Demo{
    public static void main(String[] args){
        B b = new B();
        b.show();
    }
}
class A{
    int num =10;
}
class B extends A{
    int num = 20;
    public void show(){
        int num = 30;
        System.out.println("num="+num);//调用局部变量中的num
        System.out.println("this.num=" +this.num);//调用本类中的num变量
        System.out.println("super.num="+super.num);//调用父类中的num变量
    }
}

这里写图片描述

方法(函数)的重写

函数的重写(Override)
1.子类的方法与父类的方法必须完全相同的: 返回值类型 方法名 参数列表
2.访问修饰符:子类必须拥有同父类相同或者更宽的访问修饰符

class Demo{
    public static void main(String[] args){
        B b = new B();
        b.show("小明",20);
    }
}
class A{
    public void show(String name,int age){
        System.out.println("A.show()");
    }
}
class B extends A{
    public void show(String name,int age){
        super.show(name,age);//在子类中可以访问被覆盖的父类的方法,可以不在第一行
        System.out.println("B.show()"); 
    }
}

多态

前提:

  • 需要存在继承或者实现关系
  • 要有覆盖操作

成员变量:

  • 如果父类有,子类没有:访问的是父类的
  • 如果父类有,子类也有个相同的:访问的是父类的
  • 如果父类没有,子类有:编译错误
    多态时,访问的成员变量,父类必须要有,否则编译错误。而且运行时访问的是父类的

成员方法:

  • 如果父类有,子类没有:访问的是父类的
  • 如果父类有,子类重写:访问的是子类的
  • 如果父类没有,子类有:编译错误

多态时,对于重写的方法:执行期动态绑定到子类的方法,所以执行时执行的是子类。编译时,要求父类必须要有,如果没有,编译错误;编译时看父类,运行时运行的是子类的

静态的成员方法:

  • 如果父类有,子类没有:访问的是父类的
  • 如果父类有,子类重写:访问的是父类的
  • 如果父类没有,子类有:编译错误
class A{
    public int num = 10;
    public static void run(){
        System.out.println("A的run方法");
    }
    public void show(){
        System.out.println("A的show方法");
    }
}
class B extends A{
    public int num = 20;
    public static void run(){
        System.out.println("B的run方法");
    }
    public void show(){
        System.out.println("B的show方法");
    }
}

class Demo{
    public static void main(String[] args)  {
        A c = new B();//创建了一个A类型(父类),使用的是子类的空间
        System.out.println(c.num);//打印 10
        c.run();//打印 A的run方法
        c.show();//打印 B的show方法
    }
}

当父类引用指向子类对象时,访问的成员属性和成员方法:

  • 编译时:父类必须要有,否则编译错误
  • 运行时:成员属性和静态方法都是父类的,只有重写的成员方法运行时是运行的子类的
  • 多态时,父类的引用不能访问到子类自有的方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值