面向对象中 (五)

文章详细介绍了Java中的面向对象特性,包括继承性(一个类可以继承另一个类的属性和方法),方法的重写(子类可以覆盖父类的同名方法),以及多态性(父类引用指向子类对象的能力)。此外,还讨论了super关键字的使用,子类对象实例化过程,以及Object类中的equals()和toString()方法。文章强调了多态性在提高代码复用性和灵活性方面的价值,并给出了实例说明。
摘要由CSDN通过智能技术生成

Java面向对象 ( 中 )

观看b站尚硅谷视频做的笔记

1、 面向对象特征之二:继承性 (inheritance)

有一个Person类
发现Student类也有Person类这些属性,多了一个属性
在这里插入图片描述
在这里插入图片描述
测试类
在这里插入图片描述
目前Pesron类和Student类没有任何关系
但是Pesron类和Student类都有一些共同

既然Pesron类已经定义过了,Student类先定义的类,能不能复用一下定义已经定义好的结构

如何实现定义一个Student,不用去写一行一行代码?
继承extends
在这里插入图片描述

扩展:类与类之间都有哪些关系

继承性的好处(why为什么要有继承性)
提高的代码的复用性(谁想调就调)
多态性的前提就是需要有继承
体现:一旦子类 A 继承父类 B 以后,子类 A 就获取了父类 B 中声明的所有属性和方法。构造器本身是造对象使用的,不能说是对象去调构造器,构造器后面关键字super再讲,此处主要体现属性或方法,一旦继承后,就获取了父类的属性方法。

获取:当造对象时,通过子类对象去调属性或方法。

封装性解决的是可见性的问题
继承性解决的是能不能拿到里面结构的问题
继承性说都能拿到,能不能调还需要看封装性

Java 中关于继承性的规定:

一个父类可以有多个子类,一个类可以被多个子类继承
一个类只能有一个父类称为单继承,后续会讲接口,类是可以实现多个接口(也可以通过这样实现扩展功能)

2、方法的重写 (ocerride / overwrite)

3、关键字:super

super理解为:父类的。

super可以用来调用:属性、方法、构造器。

super的使用
我们可以在子类的方法或构造器中,通过super.属性或super.方法方式,显式的调用父类中声明的属性或方法,但是,通常情况下,习惯省略super.

特殊情况下:当子类和父类中定义了父类中定义了同名的属性,则必须显示的使用使用super.属性的方式,表面调用的是父类中声明的属性。
特殊情况:当子类重写父类中的方法,想在子类的方法中调用父类中被重写的方法,必须显示的使用super.方式表明调用的是父类中被重写的方法。

super调用构造器:在子类的构造器中显示的使用super(形参列表)的方式,调用父类中声明的指定构造器。
super(形参列表)的使用,必须声明在子类构造器的首行。

在类的构造器中,针对于this形参列表或super只能二选一,不能同时出现。

在构造器的首行,既没有显示的声明this(形参列表)或super形参列表,则默认的是调用父类中的空参构造器。super()
在类的多个构造器中,至少有一个类的构造器使用了super(形参列表)调用父类中的构造器。

重写了父类中的方法,

this关键字是属性、与形参同名,避免同名。
super关键字子父类,子类重写父类中被重写的方法,覆盖了父类中的被重写的方法,在子类中想要再调用父类中的被重写的方法,想要进行区分。
super关键字的使用

Person 类

public Person(String name,int age){
this(name);构造器
this.age = age;
}

Student 类
在这里插入图片描述
测试类

super理解为父类,所以主要在Student子类中如何调父类中的结构
在这里插入图片描述

在这里插入图片描述

public void show(){

system.out.println(“name=”+this.name+“.age=”+super.age);
}
this.name当前对象的堆空间中找name结构
什么时候用super?
Person类中定义了int id;学生类中也定义了一个int id;子父类中出现同名的属性,内存中有两个属性id
在这里插入图片描述

super调用构造器
在这里插入图片描述

4、子类对象实例化过程

Dog类的直接父类是animal

子类对象实例化过程
1.在结果上看:子类继承父类以后,就获取了父类中声明的属性或方法。
创建子类的对象中,在堆空间中,就会加载所有父类中声明的属性。
2.从过程上看:当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用父类构造器,直到调用了java.lang.Object类中空参的构造器为止。正因为加载所有的父类结构。

一个类有N个构造器,最多有n-1个this,没写那个一定是super,new dog对象会直接间接的调用animal构造器,animal会直接间接调用Creature构造器,这是为啥?

new了一dog对象,为啥有了anima的属性?

在创建子类对象时,直接间接调用了父类构造器

5、 面向对象特征之三:多态性

person类
Man 类
Woman 类
测试类

  1. 理解多态性:可以理解为一个事物的多种态性。

  2. 对象的多态性,父类的引用指向子类的对象(或子类的对象赋值给父类的引用)

  3. 多态的使用:虚拟方法调用

  4. 有了对象多态性以后,在编译器,只能调用父类声明的方法,但在执行实际执行的是子类重写父类的方法。简称,编译时,看左边,运行时看右边。若 编 译 时 类 型 和 运 行 时 类 型 不 一 致, 就 出 现 了 对 象 的 多 态 性
    (Polymorphism)。
    多态情况下:
    看左边:看的是父类的引用(父类中不具备子类特有的方法)
    看右边:看的是子类的对象(实际运行的是子类重写父类的方法)

  5. 多态性的使用前提:
    ① 类的继承关系;
    ② 方法的重写。

  6. 对象的多态性:只适用于方法,不适用于属性 ( 编译和运行都看左边 )

Person p2 = new Man();
p2.eat();
p2.walk();
编译时看左边的类型,执行时子类重写的方法
父类的引用 p2
子类的对象new Man();
调子类方法不能调,p2.earnMoney();
.出来的是Person类的

package com.zhou.java;

public class PersonTest {


    public static void main(String[] args) {
        Person person = new Person();
        person.eat();


        Man man = new Man();
        man.eat();
        man.age = 25;
        System.out.println(man.age);
        man.earnMoney();

        System.out.println("************************************");
        //对象的多态性:父类的引用指向子类的对象
        Person p = new Man();
        Person p1 = new Woman();

        //多态的使用:当调用子父类同名参数方法时,实际调用的是子类重写父类的方法--虚拟方法调用
      // .出来的是Person类的
        p.eat();
        p1.eat();
     //子类方法不能调
        p1.earnMoney();


    }
}

class Person {
    String name;
    int age;

    public void eat() {
        System.out.println(" 人,吃饭 ");
    }

    public void walk() {
        System.out.println(" 人,走路 ");
    }
}


class Woman extends Person {
    boolean isBeauty;


    public void goShopping() {
        System.out.println("女人喜欢购物");
    }

    public void eat() {
        System.out.println(" 女人少吃,为了减肥 ");
    }

    public void walk() {
        System.out.println(" 女人,窈窕的走路 ");
    }

}


class Man extends Person {
    boolean isSmoking;

    public void earnMoney() {
        System.out.println("男人负责工作养家");
    }

    public void eat() {
        System.out.println(" 男人多吃,长肌肉 ");
    }

    public void walk() {
        System.out.println(" 男人霸气走路 ");
    }

}

为什么要有多态性?为什么要用多态性?
举例一
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.func(new Dog());此处要传一个实例
test.func(new Cat());
}
public void func(Animal animal){//Animal animal = new Dog();
animal.eat();因为声明的是Animal类型,只能调Animal的方法,执行的时候子类重写后的方法
animal.shout();
}

package com.zhou.java;

public class AnimalTest {
    public static void main(String[] args) {
        AnimalTest animalTest = new AnimalTest();
        animalTest.fun(new Dog());
        animalTest.fun(new Cat());
    }


    public void fun(Animal animal) {//Animal animal=(new Dog()
        animal.eat();
        animal.shout();


    }


    // 如果没有多态性,就会写很多如下的方法,去调用

    public void func(Dog dog) {
        dog.eat();
        dog.shout();

    }

    public void func(Cat cat) {
        cat.eat();
        cat.shout();

    }


}


class Animal {

    public void eat() {
        System.out.println(" 动物,进食 ");
    }

    public void shout() {
        System.out.println(" 动物:叫 ");
    }

}


class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃骨头");

    }


    public void shout() {


        System.out.println("汪汪汪");
    }
}


class Cat extends Animal {
    public void eat() {
        System.out.println(" 猫吃鱼 ");
    }

    public void shout() {
        System.out.println(" 喵!喵!喵! ");
    }
}

举例二
在这里插入图片描述
class Order{
public void method(Object obj){传任何一个对象都可以
}

}

举例三
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
对象的多态性:只适用于方法,不适用于属性 ( 编译和运行都看左边 )
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.zhou.java;

public class PersonTest1 {

    public static void main(String[] args) {

        Person1 person1 = new Man1();
        System.out.println(person1.age);



    }
}


class Person1 {
    String name;
    int age = 1001;


    public void eat() {


        System.out.println("人,吃饭");
    }

    public void walk() {


        System.out.println("人,走");
    }
}





class  Man1 extends Person1 {
    boolean isSmoking;
    int id = 1002;




}

在这里插入图片描述

5.1、 虚拟方法的补充

在这里插入图片描述

从编译和运行的角度看:
重载,是指允许存在多个同名方法,而这些方法的参数不同。


编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java 的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。
引用一句 Bruce Eckel 的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”

5.2、向下转型的使用

在这里插入图片描述

// 如何才能调用子类所特有的属性和方法?
对编译器来讲,声明的p2不再是Person类型就行

赋值左边右边要么类型需要一样,要么像基本数据类型中自动提升,子类对象可以赋给父类,
在这里插入图片描述
基本数据类型int–double,直接转,称为自动类型提升
在这里插入图片描述
基本数据类型double-int,使用强制类型转换,用()里面放需要转换的类型(double)
Man m1 = (Man) p2;
m1.earnMoney();
m1.isSmoking = true;
在内存中的结构?
一开始栈中声明了p2,堆空间这new了一个man对象,man对象中有person父类的对象中的属性与方法,也有man中的属性与方法,man对象中的地址值赋给p2,地址值有两个部分:前面是类型,后面是@地址,因为地址值有类型的限制,直接赋值给m1时,就不让赋值,使用(man)强转,就可以了,将地址完全就赋值过来给m1,即m1指向man对象,编译器认为此时是Man类型,即就可以去调man对象中的属性与方法
// 使用强转时,可能出现 ClassCastException 异常
Woman w1 = (Woman)p2;因为此时的p2是man

为了避免这种方式的出现?使用instanceof

任何一个类的对象可以作为Object类的实例

// 向下转型的常见问题
// 问题二 : 编译通过,运行时也通过,这是可以的
Object obj = new Woman();
Person p = (Person)obj;
在这里插入图片描述
woman赋给obj,向上转型(多态性),再将obj强转成person

编译通过,运行不通过
Person p4 = new Person();
Man m4 = (Man)p4;

Object o = new Date();
// String str1 = (String)o;


```java
package com.zhou.java;

public class PersonTest2 {
    public static void main(String[] args) {

        Person2 p2 = new Man2();
        // p2.earnMoney();
        // 不能调用子类所特有的方法、属性,编译时,p2 是 Person类型
        //有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,
        // 但是由于变量声明为父类类型,导致编译时,只能调用父类中的属性和方法。子类的属性和方法不能调用

        // 如何才能调用子类所特有的属性和方法?对编译器来讲,声明的p2不再是Person类型就行
        // 赋值左边右边要么类型需要一样,要么像基本数据类型中自动提升,子类对象可以赋给父类
//使用强转,也可称向下转型:

        Man2 m2 = (Man2) p2;
        m2.earnMoney();
        m2.isSmoking = true;


// 使用强转时,可能出现 ClassCastException 异常
        // Woman2 w2=(Woman2) p2;
        //  w2.goShopping();


        //    为了避免这种异常ClassCastException 异常出现?使用instanceof
// a instanceof A:判断对象a是否是类A的实例,如果是,返回true,如果不是,返回false

      /*  使用情境:为了避免在向下转型时出现 ClassCastException
        异常,我们在进行向下转型之前,先进行 instanceof 的判断 , 一旦返回
        true, 就进行向下转型。如果返回 false,不进行向下转型。
        如果a instanceof A返回true,则a instanceof B也返回true,其中类B是类A的父类。
        */
if(p2 instanceof Woman2){

    Woman2 w3=(Woman2)p2;
    w3.goShopping();
    System.out.println("**********Woman*********");
}
if (p2 instanceof  Man2){

   Man2 m3= (Man2) p2;
   m3.earnMoney();
    System.out.println("**********Man*********");
}


        if (p2 instanceof  Person2){

            Person2 p3= (Person2) p2;

            System.out.println("**********Person*********");
        }


        if (p2 instanceof Object){


            System.out.println("**********Object*********");
        }

//向下转型的常见问题:
       //问题1 :编译通过,运行不通过
    // Person2 p4=   new Woman2();
    // Man2 m4=(Man2) p4;

       // Person2 p5= new Person2();
      //  Man2 m5=(Man2) p5;


        //问题2 :编译通过,运行通过

       Object obj=   new Woman2();
       Person2 p5=(Person2) obj;


        //问题3 :编译不通过,运行不通过


     //   Man2 m6 = new woman2();

//		String str = new Date();

//		Object o = new Date();
//		String str1 = (String)o;



    }


}


class Person2 {

    String name;
    int age;

    public void eat() {
        System.out.println(" 人,吃饭 ");
    }

    public void walk() {
        System.out.println(" 人,走路 ");
    }
}

class Woman2 extends Person2 {
    boolean isBeauty;

    public void goShopping() {
        System.out.println(" 女人喜欢购物 ");
    }

    public void eat() {
        System.out.println(" 女人少吃,为了减肥。");
    }

    public void walk() {
        System.out.println(" 女人,窈窕的走路。");
    }
}


class Man2 extends Person2 {
    boolean isSmoking;

    public void earnMoney() {
        System.out.println(" 男人负责工作养家 ");
    }

    public void eat() {
        System.out.println(" 男人多吃肉,长肌肉 ");
    }

    public void walk() {
        System.out.println(" 男人霸气的走路 ");
    }
}

引用数据类型的==,
System.out.println(b == s); //true比较的是两个引用数据类型变量的地址值是否相同。
System.out.println(b.count); //10,多态性不适用于属性
b.display();20

  1. 若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中。编译看左边,运行看右边
    1. 对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量。编译运行都看左边
  • package com.zhou.java;

public class MethodTest {
public static void main(String[] args) {

    Sub sub = new Sub();
    System.out.println(sub.count);
    sub.display();



    Base b= sub;
    System.out.println(b==sub);
    System.out.println(b.count);
    b.display();


}

}

class Base{

int count= 10;
public void display() {
    System.out.println(this.count);
}

}
class Sub extends Base{

int count= 20;
public void display() {
    System.out.println(this.count);
}

}
``
在这里插入图片描述

6、Object 类的使用

6.1 、Object 类中的主要结构

java.lang.Object类
1)Objetc类是所有Java类中的根父类
2)如果在类的声明中未使用extends关键字指明其父类,则默认父类java.lang.Object类
3)Object类中的功能(属性、方法)就具有通用性
属性:无
方法:equals()、toString()、getClass()、hashCode() clone() / finalize() / wait() / notify() / notifyAll()。

xxx.getClass().getSuperClass()获取xxx是谁造的,然后再获取它的父类。

Object定义在lang包下

4)Object只声明了一个空参构造器,造的所有对象都会调用到Object类的空参构造器
在这里插入图片描述

finalize方法:
若对象在栈中没有任何引用指向,就会调用finalize方法,将堆空间中的实体进行回收
通常情况都不会主动调用此方法,垃圾收集器自动调。
在这里插入图片描述
在这里插入图片描述

6.2 、== 操作符与 equals 方法

一、= =运算符:
1)可以使用在基本数据类型和引用数据类型变量当中
2)如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一定类型要相同)
如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。补充==符号使用时,必须保证符合左边两边的变量类型一致
测试
二、equals() 方法的使用
1.)是一个方法,而运算符
2)只能适用于引用数据类型
3)Object类中equals()方法的定义

public boolean equals(Object obj){
return (this == obj);
}
说明:Object类中定义的equals()方法和= =作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。
4)像String、Date、File、包装类等都重写了Object类中的equals()方法,两个引用的地址是否相同,而是比较两个对象的实体内容是否相同。
5)通常情况下,我们自定义的类如果使用equals()的话,也通常时比较两个对象的实体内容是否相同,那么,我们就需要对Object类中的equals()进行重写。
重写的原则:比较两个对象的实体内容是否相同。

package com.zhou.java;

import java.util.Date;

public class EqualsTest {
    public static void main(String[] args) {
        int i = 10;
        int j = 10;

        double d = 10.0;
        boolean a = true;
        System.out.println(i == j);
        System.out.println(j == i);
        //   System.out.println(a==j);

        char c = 10;
        System.out.println(i == c);

        char c1 = 'A';
        char c2 = 65;

        System.out.println(c1 == c2);


        //引用数据类型
        Customer cust1 = new Customer("Tom", 21);
        Customer cust2 = new Customer("Tom", 21);
        System.out.println(cust1 == cust2);

        String str1 = new String("BAT");
        String str2 = new String("BAT");
        System.out.println(str1 == str2);

        System.out.println(cust1.equals(cust2));
        System.out.println(str1.equals(str2));


        Date date1 = new Date(23432525324L);
        Date date2 = new Date(23432525324L);
        System.out.println(date1 == date2);
        System.out.println(date1.equals(date2));


    }
}

class Customer {
    private String name;
    private int age;




    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Customer() {
        super();
    }

    public Customer(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;


        }
        if (obj instanceof Customer) {
            Customer cust = (Customer) obj;
            //比较两个对象的属性是否相同
            if (this.age == cust.age && this.name.equals(cust.name)) {
                return true;

            } else {

                return false;
            }


        }
        return false;
    }

}

6.3、 重写 equals() 方法的原则

对称性:如果 x.equals(y) 返回是“true”,那么 y.equals(x) 也应该返回
是“true”。
自反性:x.equals(x) 必须返回是“true”。
传递性:如果 x.equals(y) 返回是“true”,而且 y.equals(z) 返回是“true”,
那么 z.equals(x) 也应该返回是“true”。
一致性:如果 x.equals(y) 返回是“true”,只要 x 和 y 内容一直不变,
不管你重复 x.equals(y) 多少次,返回都是“true”。
任何情况下,x.equals(null),永远返回是“false”;x.equals( 和 x 不同类
型的对象 ) 永远返回是“false”。

6.4、 toString 的使用

Object类中toString()的使用
1)当我们输出一个引用对象时,实际就是调用当前对象的toString方法
2)Object类中的toSring的定义方法
public String toString(){
return getClass.getName()+“@”+Integer.toHexString(hashCode())
}
3)像String、Date、File、包装类都重写了Objetc类中的toString()方法。使得在调用toString()时,返回实体内容信息。
4)自定义类如果重写toString()方法,当调用此方法时,返回对象的实体内容。

public class ToStringTest {

String str = new String(“MM”);
System.out.println(str);为啥这里出来不是地址值,就只有String重写过
自定义类重写toString()
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
想看对象的信息,就直接重写toString方法

在这里插入图片描述

在这里插入图片描述

package com.zhou.java;

import java.util.Date;

public class EqualsTest {
    public static void main(String[] args) {
        int i = 10;
        int j = 10;

        double d = 10.0;
        boolean a = true;
        System.out.println(i == j);
        System.out.println(j == i);
        //   System.out.println(a==j);

        char c = 10;
        System.out.println(i == c);

        char c1 = 'A';
        char c2 = 65;

        System.out.println(c1 == c2);


        //引用数据类型
        Customer cust1 = new Customer("Tom", 21);
        Customer cust2 = new Customer("Tom", 21);
        System.out.println(cust1 == cust2);

        String str1 = new String("BAT");
        String str2 = new String("BAT");
        System.out.println(str1 == str2);

        System.out.println(cust1.equals(cust2));
        System.out.println(str1.equals(str2));


        Date date1 = new Date(23432525324L);
        Date date2 = new Date(23432525324L);
        System.out.println(date1 == date2);
        System.out.println(date1.equals(date2));


    }
}

class Customer {
    private String name;
    private int age;




    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Customer() {
        super();
    }

    public Customer(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;


        }
        if (obj instanceof Customer) {
            Customer cust = (Customer) obj;
            //比较两个对象的属性是否相同
            if (this.age == cust.age && this.name.equals(cust.name)) {
                return true;

            } else {

                return false;
            }


        }
        return false;
    }


    @Override
    public String toString() {
        return "Customer\"[\"name=\"+name+\",age=\"+age]";
    }
}
package com.zhou.java;

public class ToStringTest {
    public static void main(String[] args) {
        Customer cust1 = new Customer("Tom",21);
        System.out.println(cust1);
        System.out.println(cust1.toString());


        String str = new String("MM");
        System.out.println(str);


    }




}

在这里插入图片描述

7、包装类 (Wrapper) 的使用

7.1 、单元测试方法的使用

java中JUnit单元测试

步骤 :

  1. 选中当前项目工程 --》 右键:build path --》 add libraries --》
    JUnit 4 --》 下一步;
  2. 创建一个 Java 类进行单元测试。
    此时的 Java 类要求:①此类是公共的 ②此类提供一个公共的无参构造器
  3. 此类中声明单元测试方法。
    此时的单元测试方法:方法的权限是 public, 没有返回值,没有形参。
  4. 此单元测试方法上需要声明注解:@Test 并在单元测试类中调用:
    import org.junit.Test;
  5. 声明好单元测试方法以后,就可以在方法体内测试代码。
  6. 写好代码后,左键双击单元测试方法名:右键 --》 run as --》
    JUnit Test;
    说明:如果执行结果无错误,则显示是一个绿色进度条,反之,错误
    即为红色进度条。在这里插入图片描述
    原来讲的:定义了一个成员变量,在main方法中调用,需要在main方法中创一个对象,通过对象.属性去调用
    现在直接可以调用
    在这里插入图片描述
package com.zhou.java;

import org.junit.Test;

public class JunitTest {
   @Test
    public void testEquals(){

       int num=10;
       String s1="MM";
       String s2="MM";
       System.out.println(s1.equals(s2));
       System.out.println(num);

     //ClassCastException 的异常
      /*Object obj = new String("GG");
     Date date=(Date)obj;*/



   }
}

7.2、 包装类的使用

java提供了8种基本数据类型对应的包装类,使得本数据类型的变量具有类的特征
在这里插入图片描述
注意:其中Byte,Short,Integer、Long、Float、Double的父类是:Number

7.3、包装类与基本数据类型相互转换

在这里插入图片描述
基本数据类型与包装类如何转换?
字符串转换为基本数据类型?
在这里插入图片描述
在这里插入图片描述
1) 基本数据类型 --》包装类 , 调用包装类的构造器(应用场景:有方法的形参是Object类型,就必须把基本数据类型转换成包装类,形参才能用)
@Test
public void test1() {

Integer in1 = new Integer(num1);
此时in1就是把10包装起来的包装类

package com.zhou.java;

import org.junit.Test;

public class WrapperTest {

    //基本数据类型--包装类,调用包装类的构造器
    @Test
    public void test1() {
        int num = 10;
        Integer in1 = new Integer(num);
        System.out.println(in1.toString());


        Integer in2 = new Integer("123");
        System.out.println(in2.toString());

        //  报异常
        //  报异常
        /*Integer in3 = new Integer("123abc");
        System.out.println(in3.toString());*/


        Float f1 = new Float(12.3f);
        Float f2 = new Float("12.3");
        System.out.println(f1);
        System.out.println(f2);


        Boolean b1 = new Boolean(true);
        System.out.println(b1);
        Boolean b2 = new Boolean("true");
        System.out.println(b2);

        Boolean b3 = new Boolean("true123");
        System.out.println(b3);


        Order order = new Order();
        System.out.println(order.isMale);
        System.out.println(order.isFemale);


    }


}


class Order {
    boolean isMale;
    Boolean isFemale;


}

在这里插入图片描述
2)包装类 --》 基本数据类型 : 调用包装类的 xxxValue()

package com.zhou.java;

import org.junit.Test;

public class WrapperTest {
 //   包装类 --》 基本数据类型:调用包装类的xxxValue()
    @Test
   public void Test2(){


        Integer in1 = new Integer(12);
        int i = in1.intValue();
        System.out.println(i+1);


        Float f1 = new Float(12.3f);
        float v = f1.floatValue();
        System.out.println(v+1);



    }





}

在这里插入图片描述

3)JDK 5.0 新特性 : 自动装箱与自动拆箱

public void method(Object obj){
System.out.println(obj);
}

真正调method这个方法的时候,可以传Objetc类型的子类对象,
在这里插入图片描述但是现在这会儿将num1放进去也没事儿

正常来讲num1是不能放到method里的
在这里插入图片描述
在这里插入图片描述
怎么解释这个? Object obj = num1
这里并不是//将int num1赋给Object obj ,这是错误的
这里是因为自动装箱,自动拆箱
// 自动装箱 :就可以替代包装类 , 调用包装类的构造器,就用不着我们去new了

package com.zhou.java;

import org.junit.Test;

public class WrapperTest {
//JDK 5.0 新特性 : 自动装箱与自动拆箱
    @Test
   public void Test3() {

       // int num1=10;
      //  method(num1);
        // 以前真正调method这个方法的时候,
        // 可以传Objetc类型的子类对象,正常来讲num1是不能放到method里的,
        // 但是现在这会儿将num1放进去也没事儿
      /*  怎么解释: Object obj = num1
        这里并不是//将int num1赋给Object obj ,这是错误的
        这里是因为自动装箱,自动拆箱
自动装箱 :就可以替代包装类 , 调用包装类的构造器,就用不着去new了*/


//自动装箱:基本数据类型--》包装类
      int num2=10;
    Integer in1=num2;//自动装箱

        boolean b1=true;
        boolean b2=b1;//自动装箱


        //自动拆箱:包装类--》基本数据类型
        System.out.println(in1);


      int num3=  in1;

    }


    public  void method(Object obj){
        System.out.println(obj);


    }

}

在这里插入图片描述

4)基 本 数 据 类 型、 包 装 类 —》String 类 型, 调 用 String 重 载 的valueOf(Xxx xxx)

package com.zhou.java;

import org.junit.Test;


/*基 本 数 据 类 型、 包 装 类 ---》String 类 型,
        调 用 String 重 载 的valueOf(Xxx xxx)*/
public class WrapperTest {
    @Test
    public void test4(){

        int num1=10;
        //方式一:连接运算
        String str1=num1+" ";
        System.out.println(str1);
        //方式二:调用Sting的valuseOf()

        float f1=12.3f;
        String s = String.valueOf(f1);
        System.out.println(s);


        Double d1=new Double(12.5);
        String s1 = String.valueOf(d1);
        System.out.println(s1);



    }
}

5)String 类型 —> 基本数据类型、包装类 , 调用包装类的 parseXxx()

// 错误的情况,可能会报错
// int num1 = (int)str1;
// Integer in1 = (Integer)str1;发生强转的是str1和 Integer 必须是有子父类关系

可能会报NumberFormatException
int num2 = Integer.parseInt(str1);
System.out.println(num2 + 1); //124

String str2 = “true”,
String str2 = “true”;
Boolean b1 = Boolean.parseBoolean(str2);
System.out.println(b1);false
在这里插入图片描述
在这里插入图片描述

package com.zhou.java;

import org.junit.Test;

//String 类型 ---> 基本数据类型、包装类 , 调用包装类的 parseXxx()
public class WrapperTest {

    @Test
    public void test5(){

        String str1="123";
        //错误的情况:
        // String str1="123abc";



        int i = Integer.parseInt(str1);
        System.out.println(i);

        String str2="true";
        boolean b = Boolean.parseBoolean(str2);
        System.out.println(b);
        


    }

}

8、练习

8.1继承性练习

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

8.2向下转型练习

8.3多态练习

在这里插入图片描述
在赋值的时候,体现为多态性
是Student,就调studen方法,若是Graduate,那就调graduate,是Person就调Person中的方法

在这里插入图片描述
属于多态
在这里插入图片描述
在这里插入图片描述
先写范围小的
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.exer.java;

public class InstanceTest{

    public static void main(String[] args) {


        InstanceTest t1 = new InstanceTest();
        t1.method(new Student());

    }

        public void method(Person e){
            String info = e.getInfo();
            System.out.println(info);



            if ( e instanceof  Graduate){
                System.out.println(" a graduate student");
                System.out.println(" a  student");
                System.out.println(" a person");

            }else if( e instanceof Student){

                System.out.println(" a student");
                System.out.println(" a person");
            }else {
                System.out.println(" a person");


            }


        }







}
class Person{
 protected String name="person";
 protected int  age=50;

 public  String getInfo(){
     return "name:"+name+",age:"+age;
 }



}

class Student extends Person {
    protected String school="pku";
    public String getInfo(){


        return "name:"+name+",age:"+age+"school:"+school;
    }



}



class Graduate extends Student {
    public String mjor="it";
    public String getInfo(){

        return "name:"+name+",age:"+age+"school:"+school+"major:"+mjor;

    }



    }

在这里插入图片描述

在这里插入图片描述

8.3==与equals练习

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
比地址在这里插入图片描述
在这里插入图片描述

为什么是true?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8.4Object类练习

在这里插入图片描述

8.4包装类练习

在这里插入图片描述

9、面试题

9.1、区分方法的重载与重写:

重载:1方法名相同,形参列表不同(形参个数不同、形参类型不同)
重写:发生在继承中,方法名与父类方法名相同,形参列表相同。

9.2、多态是编译时行为还是运行时行为?如何证明?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行时才知道真正创建的对象是谁,进而知道调的子类的方法是谁
在这里插入图片描述

在这里插入图片描述

9.3、final,finall,finalize的区别?

9.4、==和equals的区别?

9.5、包装类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
println()里面放char型数组,输出的是内容,除了char型数组都是地址值

Integer m=1;此处不是new的方式
Integer n=1;
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[]
保存了从-128到127范围的正数,如果我们使用自动装箱的方式,给Integer赋值的范围在-128到127范围i内,可以直接使用数组中的元素,不用再去new了
在这里插入图片描述
在这里插入图片描述

10、项目

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值