欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java学习【Day 4】

程序员文章站 2022-03-08 11:57:29
...

this()

通过当前的构造方法去调用本类的另一个构造方法。可以做到代码复用。

this(实际参数列表);

且这样的写法只能作为构造方法的第一个语句

public class Test_this {
    public int year;
    public int month;
    public int day;

    //无参构造方法
    public Test_this(){
        this(2021,5,27);  //调用了有参构造方法
    }

    //有参构造方法
    public Test_this(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

}

继承

有了继承关系,才有了方法的覆盖和多态机制
语法:

class 类名 extends 父类名{
	类体;
}

继承的特性:

  1. B类继承A类。称A类是超类(superclass)、父类、基类;称B类是子类(subclass)、派生类、扩展类
  2. java只支持单继承,不能多继承。
  3. 虽然java不支持多继承,但能产生间接继承的效果
  4. 子类继承父类,除构造方法不能继承之外,剩下的都可以继承。父类中private修饰的属性不能在子类中直接访问,但可以间接通过别的方法访问。
  5. java中的类如果显示没有继承任何类,则默认继承Object类。Object是所有类的父类。继承结构中最顶点的是:Object
  6. 继承也有缺点,会导致两个类的耦合度高,父类的改变会影响的子类。

继承的例子:

package Demo;

public class Test_extends {
    public static void main(String[] args){
        CreditAccount cust1 = new CreditAccount();
        cust1.setBalance(6.66); //使用父类的方法
        System.out.println(cust1.getBalance());
    }
}

//银行账户
//账号、余额
class Account {
    private String autno;
    private double balance;

    public Account(){

    }

    public Account(String autno,double balance){
        this.autno = autno;
        this.balance = balance;
    }

    public void setBalance(double balance){
        this.balance = balance;
    }

    public double getBalance(){
        return this.balance;
    }
}

//信用卡账户
//账号、余额、信誉度
class CreditAccount extends Account{

    private double credit;   //信誉度属性

    public CreditAccount(){

    }

    public void dosome(){
        System.out.println(getBalance());
    }

    public void setCredit(double credit){
        this.credit = credit;
    }

}

方法覆盖

又名方法重写。子类继承父类的方法,并对其进行重写。

覆盖的条件:

  1. 两个类必须要有继承关系
  2. 重写之后的方法和之前的方法具有:相同的返回值类型、相同的方法名、相同的形参
  3. 访问权限不能更低,可以更高(比如高权限public不能被重写成低权限的privated、protected)
  4. 重写之后的方法不能比之前的方法抛出更多的异常,可以更少

方法覆盖的注意事项:

  1. 方法覆盖针对方法,和属性无关
  2. 私有方法不能被覆盖
  3. 构造方法不能被覆盖,因为构造方法不能被继承
  4. 方法覆盖只只针对“实例方法”,“静态方法的覆盖”没有意义
package Demo;

public class Test_Override {
    public static void main(String[] args){
        Chinese p1 = new Chinese();
        p1.setName("小宏");
        p1.speak();

        English p2 = new English();
        p2.setName("DMIND");
        p2.speak();
    }
}

class People{
    private String name;
    //构造方法
    public People(){};
    public People(String name){
        this.name = name;
    }

    //setName和getName
    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return this.name;
    }

    public void speak(){
        System.out.println(this.getName()+" ....");
    }
}

class Chinese extends People{
    public void speak(){
        System.out.println(this.getName()+"说汉语");
    }
}

class English extends People{
    public void speak(){
        System.out.println(this.getName()+"说嘤语");
    }
}

多态

多种状态,多种形态。编译和运行有两个不同的状态
编译期叫做静态绑定
运行期叫做动态绑定

Animal a = new Cat();
编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move方法,找到了就绑定,编译通过。
但运行的时候和底层堆内存当中的实际对象有关
真正执行的时候会自动调用 “ 堆内存中真实对象 ”的相关方法

向上转型:子------>父(upcasting)
又被称为自动类型转换。 Animal a = new Cat();

向下转型:父------>子(downcasting)
又被称为强制类型转换。Cat c = (Cat) a; 需要添加强制类型转换符

不管时向上转型还是向下转型,首先他们之间要有继承关系,这样编译器就不会报错

什么时候要向下转型?
需要调用或者执行子类对象中特有的方法时。必须进行向下转型才能调用。

向下转型的风险?
容易出现 ClassCastException(类型转换异常)

如何避免这个风险?
使用 instanceof运算符,可以在程序执行阶段动态的判断某个引用指向的对象。养成好习惯:在向下转型之前一定要使用 instanceof 运算符进行判断。

instanceof

可以在运行阶段动态判断引用指向的对象的类型。返回Boolean值

引用 instanceof 类型

a1 instanceof Cat

关于多态与instanceof的例子:

package Demo;

public class Test_duotai {
    public static void main(String[] args){
        Animal a2 = new Bird();  //向上转型
        Animal a1 = new Cat();  //向上转型
        a1.move();
       
        //a1.Catchmouse();    //这句会报错的,因为无法通过编译阶段,编译时认为a1是Animal类所以找不到Carchmouse()而报错
        Cat x = (Cat)a1;   //想要调用Cat类特有的方法就得:向下转型。使用了强制转换符。
        x.Catchmouse();     //成功调用特有方法
        

        //向下转型前,使用instanceof进行判断,避免出现:ClassCastException(类型转换异常)
        if(a2 instanceof Bird){
            Bird y = (Bird)a2;
            y.Sing();
        }
        else if (a2 instanceof Cat){
            Cat y = (Cat)a2;
            y.Catchmouse();
        }
    }
    
}


class Animal{
    public void move(){
        System.out.println("动物移动");
    }
}

class Cat extends Animal{
    public void move(){
        System.out.println("猫移动");
    }

    //抓老鼠
    public void Catchmouse(){
        System.out.println("猫抓老鼠");
    }
}
class Bird extends Animal{
    public void move(){
        System.out.println("鸟移动");
    }

    //歌鸣
    public void Sing(){
        System.out.println("鸟在歌鸣");
    }
}

静态方法 “不存在” 覆盖

一般情况下,我们说静态方法 “不存在” 覆盖。静态方法的执行不需要对象
静态方法虽然可以使用引用.的方式来调用,但是和对象没有关系,最后还是执行Animal.dosome()

package Demo;

public class Test_duotai {
    public static void main(String[] args){
        Animal a1 = new Cat();  //向上转型
        a1.dosome();
}


class Animal{
    public static void dosome(){
        System.out.println("Aniaml的静态方法执行了");
    }
}

class Cat extends Animal{
    public static void dosome(){
        System.out.println("Cat的静态方法执行了");
    }
}

//Aniaml的静态方法执行了
相关标签: Java