JAVA学习之内部类以及常用类

版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/qq_37757008/article/details/81408567 https://blog.csdn.net/qq_37757008/article/details/83218586

内部类

内部类按位置分为成员内部类和局部内部类,而这些在我的上一篇博客中有了很详细的讲解,今天我们主要学习了一下匿名内部类。

  • 匿名内部类:
    匿名内部类:他就是是局部内部类的简写方式。
    匿名内部类本质是一个对象!
    那么它是是谁的对象呢?
    答:是实现了该接口或继承了该抽象类的子类对象
    说简单点就是我们在使用某些方法时,我们可能只想使用一次,这时候我们没必要专门去声明一个子类对象,这时候我们就可以直接声明一个匿名的内部类,实现一下想要实现的功能即可。
public abstract class Animal {
    public abstract void show();
}
public class Dog extends Animal{
    @Override
    public void show() {
        System.out.println("dog继承Animal后重写的方法");
    }
}
public class MyDemo3 {
    public static void main(String[] args) {
        new Animal() {   		//匿名内部类
            @Override
            public void show() {
                System.out.println("我重写了dog的show方法");
            }
        }.show();

       testMethod(new Animal() {
           @Override
           public void show() {
               System.out.println("我再次重写了dog的show方法");
           }
       });     //匿名内部类可以当参数传递
    }
    private static void testMethod(Animal an) {
        an.show();
    }
 }

从上面的例子我们可以看到,我们在main主方法中定义了一个匿名内部类new Animal(){};我们之前说过匿名内部类的本质就是对象,因此我们可以在它后面直接打点调用父类的show方法。同时它如果是个对象,我们也可以把它当作参数传入方法,testMethod(Animal an)类需要一个animal的子类对象传入,因此我们也可以声明一个匿名内部类当作参数传给它。
在这里插入图片描述

看到这里我们就知道了,匿名内部类的本质就是对象,所以它拥有对象的所有属性,包括它对方法的调用,包括它作为参数,抑或是返回值的各种属性。

但是看到这里我们就要想了,那如果我们的父类有多个方法呢?匿名内部类作为对象可以调方法是没错,可是如果我们的父类有多个方法呢,我们难道需要每次都重新声明匿名内部类去调用么?况且你重新声明的匿名内部类本质还是上一个么?答案肯定不是了,那我们如果想要用同一个匿名内部类做对象实现调用父类的多个方法时,我们怎么办呢?
这个时候我们只需给这个匿名内部类声明一个方法即可啦。

MyInterface my=  new MyInterface() {
            @Override
            public void hehe() {
                System.out.println("重写hehe");
            }

            @Override
            public void haha() {
                System.out.println("重写haha");
            }
        };
      	my.haha();
      	my.hehe();

我们上面的例子就是如此,声明一个接口的匿名对象,给他一个名字叫my,这样我们就可以调用接口中的多个方法了。


JAVA常用类之Object类

这次我按思维导图的方式进行总结;

在这里插入图片描述
一般重写的tostring类源码:

public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

一般重写的equals类源码:

 public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;   
        //这里定义的对象是根据你的需求的,在定义时可以灵活的选择你的声明对象。
        return age == student.age &&
                Objects.equals(name, student.name);
    }

JAVA常用类之Scanner类

在这里插入图片描述
以上是Scanner类中常用的一些方法
常用格式

Scanner sc = new Scanner(System.in);
int num = sc.nextInt();   //获取一个Int型数据,根据需求选择输入的数据类型

JAVA常用类之String类

在这里我们还要深刻理解String类的两种实例化方法的本质不同。
在这里插入图片描述

public class StringDemo4 {
    public static void main(String[] args) {
        //两种定义字符串方式的区别
        String s = new String("hello");
        String s2 = "hello";
        String s3="hello";
        System.out.println(s2==s3);
        System.out.println(s==s2);

    }
}

在这里插入图片描述
我们通过以上的例子也能看出来,这两种实例化方式的本质是开辟的空间不同;采用直接赋值的方式(String str=“hello”)进行对象的实例化,则会将匿名对象“hello”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象,这样,所有直接赋值的String对象,如果利用相同的“hello”,则String对象==返回true,而构造方法形式会在栈内存和堆内存都开辟空间,两者实现地址映射的调用。


JAVA常用类之StringBuffer类

在这里插入图片描述

  • String和StringBuffer的转换:
    1.String – StringBuffer
    a:通过构造方法
    b:通过append()方法

    2:StringBuffer – String
    a: 使用substring方法
    b:通过构造方法
    c:通过toString()方法

  • String和StringBuffer作为参数传递
    String:
    String虽然是引用类型,但是它是一个常量,所以在做传递的时候,完全可以将其看成基本数据类型数据进行传递
    StringBuffer:
    stringbuffer需要声明变量后,将对象作为参数传递;

  • StringBulider:
    它与stringbuffer一样也是字符串变量,但是它是非线程安全的变量;
    它是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步 效率高。


Java的包装类:

  • 包装类
    Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,为了使用方便和解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八种基本数据类型对应的类统称为包装类;
  • byte----Byte
    short----Short
    int -----Integer
    long----Long
    char----Character
    float----Float
    double—Double
    boolean—Boolean
  • Integer( int value):
    构造一个新分配的 Integer 对象,它表示指定的 int 值;
    Integer(String s):
    构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值;
    总之Integer是int型数据的一个包装类,这也符合了Java万物皆对象的思想,给int型常量提供了一些方法。
    Integer.parseInt(str),这是比较推荐的integer方法,将String型数据转换为int型数据。
    同理,以上的八种包装类都可以用Xxx.parseXxx(str)的方式将对应的字符型数字转变为对应的数据类型;
    这里我们要说一下基本数据类型和对应包装类的转换方式,我们这次以double和Double作为例子;
		double d=3.14;
        Double aDouble = new Double(d);
        double v = aDouble.doubleValue();
        Double aDouble1 = Double.valueOf(d);

以上我们先用构造方法,将double型数据转换为Double,然后我们又调用doubleValue()方法,将其转换为double基本数据类型;除了构造方法的形式我们还可以用Double.valueOf()方法将其转换为对应包装类;
所有以上的方法,八种基本数据类型都可以使用,XxxValue(),将其从包装类转换为基本数据类型,Xxx.valueOf(),将基本数据类型转换为对应包装类;
而通过以上的方法虽然简单但是我们还是需要将其进行手动的转换,而对于大型的工程我们声明的基本类型很多,这种方法就很不切实际,也很麻烦,于是java也很人性化的提出了便捷的方法:自动拆装箱

自动拆装箱:

注:JDK.5之后 有自动拆装箱;
自动装箱:将基本数据类型,直接转换成对应的包装类型;

自动拆箱:将包装类型,自动转成对应的基本类型;

int num = 100;
Integer a = num;//自动装箱
Integer b = 100;//自动装箱
b = b + 20;//自动拆箱和自动装箱

从上面就能看出来,我们定义了int型数据,然后把他直接赋值给Integer型,也是可以的,这就叫自动装箱,同样Integer b = 100;这是更为直接的自动装箱;而下面的 b=b+20更是同时完成了自动拆箱和自动装箱;b+20中的b本来是我们上面装箱为Integer型的数据,它要想与20相加,就需要先自动拆箱为int型数据,与20相加后,int型数据又自动装箱为包装类型integer;

猜你喜欢

转载自blog.csdn.net/qq_37757008/article/details/83218586