Java入门小结(5)

多态中成员方法使用的特点

访问规则
看new的谁,就优先用谁,没有则向上找。

口诀:编译看左边,运行看右边。

对比
成员变量:编译看左边,运行还看左边。
成员方法:编译看左边,运行看右边。

使用多态的好处

举例:
如果不用多态,只用子类,写法是:

Teacher one = new Teacher();
one.work();// 讲课
Assistant two = new Assistant();
two.work();// 辅导

现在唯一要做的事情,就是调用work方法,其他的功能不关心。
如果使用多态的写法,那么是:

Employee one = new Teacher();
one.work();// 讲课
Employee two = new Assistant();
two.work();// 辅导

好处:无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化。

对象的向上转型

对象的向上转型,其实就是多态的写法:
格式:父类名称 对象名 = new 子类名称();
含义:右侧创建一个子类对象,把它当作父类来看待使用。
注意事项:向上转型一定是安全的。(从小范围转向了大范围)
类似于:
double num = 100;// 正确,自动类型转换

对象的向下转型

向上转型一定是安全的。但是有一个弊端:对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。
解决办法:用对象的向下转型【还原】。
格式:子类名称 对象名 = (子类名称)父类对象;
含义:将父类对象,【还原】成为本来的子类对象。
注意事项
1.必须保证对象本来创建的时候就是cat,才能向下转型为cat。
2.如果对象创建的时候不是cat,现在非要向下转型为ca,就会报错。
类似于:
int num = (int)10.0;// 可以

用instanceof关键字进行类型判断

如何才能知道一个父类引用的对象,本来是什么子类?
格式
对象 instanceof 类名称
这将会得到一个boolean值结果,也就是判断前面的对象能不能当作后面类型的实例。


(自言自语)。。。多态:左父右子;左接口,右实现类


final关键字

四种用法

1.修饰一个类
格式:
public final class 类名称 {
// 方法体
}
含义:当前这个类不能有任何的子类。
注意:一个类如果是final的,那么其中的所有成员方法都无法进行覆盖重写。
2.修饰一个方法
格式:
修饰符 final 返回值类型 方法名称(参数列表){
// 方法体
}
注意:对于类、方法来说,abstract和final关键字不能同时使用,矛盾。
3.修饰一个局部变量
基本类型:
final 数据类型 变量名 = 数据值;
final int num = 20;
num = 90;// 错误写法

引用类型:
final 数据类型 变量名 = 数据值;
final Student stu = new Student( name:“小明”);
stu.getName(“小红”);// 正确写法(地址值没有变)
注意事项:

  • 对于基本类型来说,不可变指的是变量当中的数据不可改变。
  • 对于引用类型来说,不可变指的是变量当中的地址值不可改变。
    4.修饰一个成员变量
    1)由于成员变量具有默认值,所以使用final之后必须手动赋值,这样就不是默认值了。
    2)对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值,二者选其一。
    3)必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。
private final String name = "小明";
//或者
public Person() {
    name = "小明";
}
//同时要保证全参构造方法会对final的成员变量进行赋值
public Person(String name) {
    this.name = name;
}

四种权限修饰符

publicprotected(default)private
同一个类(我自己)YYYY
同一个包(邻居)YYYN
不同包的子类(儿子)YYNN
不同包非子类(陌生人)YNNN

(Y:可以访问;N:不可以访问)

内部类

就是一个类内部包含另一个类
分类:
1.成员内部类
定义格式:

修饰符 class 外部类名称 {
    修饰符 class 内部类名称 {
        // ...
    }
    // ...
}

注意:内用外,随意访问;外用内,需要内部类对象。

2.局部内部类(包含匿名内部类)
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
定义格式:

修饰符 class 外部类名称 {
    修饰符 返回值类型 外部类方法名称 {
        class 局部内部类名称 {
        // ...
        }
    }
}

成员内部类的使用

1.间接方式:在外部类的方法中,使用内部类,然后main只是调用外部类的方法。
Body body = new Body(); // 外部类的对象
// 通过外部类的对象,调用外部类的方法,里面间接再使用内部类
body.methodBody();
2.直接方式:公式:
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称;
// 按公式写
Body.Heart heart = new Body().new Heart();
heart.beat();

内部类的同名变量访问

  • 如果出现了重名现象,那么格式是:外部类名称.this.外部类成员变量名
public class Outer {
    int num = 10; // 外部类的成员变量
    public class Inner{
        int num = 20; // 内部类的成员变量
        public void methodInner() {
            int num = 30; // 内部类成员方法的局部变量
            System.out.println(num); // 30
            System.out.println(this.num); // 20
            System.out.println(Outer.this.num); // 10
        }
    }
}

局部内部类定义

格式:

修饰符 class 外部类名称 {
    修饰符 返回值类型 外部类方法名称(参数列表) {
        class 局部内部类名称 {
         // ...
        }
    }
}

注意
类的权限修饰符
定义一个类的时候,权限修饰符规则:
1.外部类:public/(default)
2.成员内部类:public protected (default) private
3.局部内部类:什么都不能写(并不是(default))

例如:
外部类和局部内部类:

public class Outer {
    public void methodOuter() {
        class Inner {
            int num = 90;
            public void methodInner() {
                System.out.println(num);
            }
        }
        Inner inner = new Inner();
        inner.methodInner();
    }
}

主函数:

Outer obj = new Outer;
obj.methodOuter; // 90

局部内部类的final问题

  • 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。
    **备注:**从java 8开始,只要局部变量事实不变,那么final关键字可以省略。
    原因:
    1.new出来的对象在堆内存当中。
    2.局部变量时跟着方法走的,在栈内存中。
    3.方法运行结束后,立刻出栈,局部变量就会立刻消失。
    4.但是new出来的对象会在堆当中持续存在,直到垃圾回收消失。

例如:

public class Outer {
    public void methodOuter() {
        class Inner {
            int num = 20; // 或者是final int num = 20;
            public void methodInner() {
                System.out.println(num);
            }
        }
    }
}

匿名内部类

  • 如果接口的实现鳄梨(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略该类的定义,而改为使用匿名内部类。
    匿名定义的格式:
    接口名称 对象名 = new接口名称() {
    // 覆盖重写所有抽象方法
    };

例如:

    public static void main(String[] args) {
        MyInterface obj = new MyInterface() {
            @Override 
            public void method() {
              System.out.println("匿名内部类实现了方法"); 
            }
        };
        obj.method(); // 匿名内部类实现了方法
    }

匿名内部类的注意事项

对“new 接口名称() {…}”进行解析:
1.new代表创建对象的动作。
2.接口名称就是匿名内部类需要实现哪个接口。
3.{…}这才是匿名内部类的内容。

Others:
1.匿名内部类,在【创建对象】的时候,只能使用唯一的一次。
如果希望多次创建对象,而且类的内容一样的话,那么久必须使用单独定义的实现类了。
2.匿名对象,在【调用方法】的时候,只能调用唯一的一次。
如果希望同一个对象,调用多次方法,那么必须给对象起名字。
3.匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
匿名内部类和那么对象不是一回事。

接口作为成员变量类型

public class Hero {
    private String name;
    private Skill skill; // Skill是接口名称
}

接口作为方法的参数和返回值

// java.util.List是ArrayList所实现的接口
public static List<String> addName(List<String> list) {
    list.add("AA");
    list.add("BB");
    list.add("CC");
    return list;
}

Object类的toString方法

直接打印对象的名字,其实就是调用对象的toString方法,看一个类是否重写了toString方法,直接答应这个类对应对象的名字即可。

  • 如果没有重写,那么打印的就是对象的地址值;
  • 如果重写了,那么就按照重写的方式打印。

Object类的equals方法

public boolean equals(Object obj) {
    return(this == obj);
}

参数:
Object obj:可以传递任意的对象。
(引用数据类型)比较的是两个对象的地址值。

重写Object类的equals方法

问题:
隐含着一个多态:Object obj = p1 = new Person(“小红”, 18);但是多态有一个弊端:无法使用子类特有的内容(方法)。
解决:可以使用向下转型(强转)把Object类型转换为Person。
操作:

Alt+Insert->equals() and hashCode()->(建议选java7+版本)

Objects类的equals方法

  • 对两个对象进行比较,防止空指针异常。
public static boolean equals(Object a, Object b) {
    return(a == b) || (a != null && a.equals(b));
}

Date类

毫秒

System.currentTimeMillis() // 获取当前系统时间到时间原点经历了多少毫秒。

Date类的构造方法和成员方法

1.空参数的构造方法

//获取当前系统的日期和时间
Date date = new Date();
System.out.println(date);

2.带参数的构造方法
传递毫秒值,把毫秒值转换为Date日期

Date d = new Date(0L);
System.out.println(d);//时间原点

3.成员方法
把日期转换为毫秒(相当于System.currentTimeMillis())

Date date = new Date();
long time = date.getTime();
System.out.println(time);

DateFormat类中的format方法和parse方法

format方法:日期–》文本
步骤:
1.创建SimpleDateFormat对象,构造方法中传递指定的模式。
2.使用SimpleDateFormat对象中的方法format,按照构造方法中指定的模式,把Date提起转换为符合模式的字符串。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Date date = new Date();
String text = sdf.format(date);
System.out.println(text);

parse方法:文本–》日期(有异常,alt+enter,选择第一个)

Calendar类(日历类)

  • Calendar类是一个抽象类。它是无法直接创建对象使用的,它里面有一个静态方法getInstance(),改方法返回了子类对象。
  • static Calendar getInstance() 使用默认时区和语言环境获得一个日历。
Calendar c = Calendar.getInstance();// 多态
System.out.println(c);

Calendar类常用的成员方法

1.public int get(int field):返回给定日历字段的值。

Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
System.out.println(year);

2.public void set(int field, int value):将给定字段的日历字段设置为给定值。

Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR,2054);
System.out.println(year);

3.public abstract void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。

Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, amount:2);

int year = c.get(Calendar.YEAR);
System.out.println(year);

4.public Date getTime():返回一个表示此Calendar时间值(从历元到现在的毫秒偏移值)的Date对象。
(把日历对象转换为日期对象)

Calendar c = Calendar.getInstance();

Date date = c.getTime();
System.out.println(date);

System类常用方法

1.public static long currentTimeMillis():返回以毫秒值为单位的当前时间。用来测试程序的效率。

long s = System.currentTimeMillis();
for(int i = 1; i <= 9999; i++){
    System.out.println(i);
}
long e = System.currentTimeMillis();
System.out.println("程序共耗时" + (e - s) + "毫秒");

2.public static void arraycopy(Object src, int srcPos, Object dest, int desPos, int length)
将数组中指定的数据拷贝到另一个数组中。
参数:

src源数组
srcPos源数组中的起始位置
dest目标数组
sPos目标数组中的起始位置
length要复制的数组元素的数量
int[] src = {1, 2, 3, 4, 5};
int[] dest = {6, 7, 8, 9, 10};
System.arraycopy(src, srcPos:0,dest, destPos:0, length:3);
System.out.println(Arrays.toString(dest));//[1, 2, 3, 9, 10]

StringBuilder类

String类:

  • 字符串是常量,它们的值在创建后不能更改。字符串的底层是一个被final修饰的数组,不能改变,是一个常量。
  • private final byte[] value;

StringBuilder类:

  • 字符串缓冲区,可以提高字符串的操作效率(看成一个长度可以变化的字符串)。底层也是一个数组,但是没有被final修饰,可以改变长度。
  • bute[] value = new byte[16];
  • StrungBuilder在内存中始终是一个数组,占用空间少,效率高,如果超出了StrungBuilder的容量,会自动扩容。

StringBuilder的构造方法和append方法

构造方法:
1.public StringBuilder():构造一个空的StringBuilder容器。

StringBuilder bu1 = new StringBuilder();
System.out.println("bu1:" + bu1);// bu1:

2.public StringBuilder(String str):构造一个StringBuilder容器,并将字符串添加进去。

StringBuilder bu2 = new StringBuilder("abc");
System.out.println("bu2:" + bu2);// bu2:abc

append方法:

  • public StringBuilder append(…):添加任意类型数据的字符串,并返回当前对象自身。
StringBuilder bu1 = new StringBuilder();
//使用append方法往StringBuilder中添加数据
//append方法返回的是this,调用方法的对象bu1
StringBuilder bu2 = bu1.append("abc");
System.out.println(bu1);//abc
System.out.println(bu2);//abc
System.out.println(bu1 == bu2);//true 两个对象是同一个对象

//使用append方法无需接受返回值
bu1.append("abc");
bu1.append(1);
bu1.append(true);
bu1.append('中');
System.out.println(bu1);//abc1true中

//上面可以使用链式编程
//方法的返回值是一个对象,可以根据对象继续调用方法
bu1.append("abc").append(1).append(true).append('中');
System.out.println(bu1);//abc1true中

reverse方法:

bu1.append("abc").append(1).append(true).append('中')//reverse方法
bu1.reverse();

//toString方法(将缓冲区内容转换为字符串)
System.out.println(bu1);//中eurt1cba

toString方法:
StringBuilder和String可以相互转换:
1.String–》StringBuilder:可以使用StringBuilder的构造方法。

  • StringBuilder(String str):构造一个字符串生成器,并初始化为指定的字符串内容。

2.StringBuilder–》String:可以使用StringBuilder中的toString方法。

  • public String toString():将当前StringBuilder对象转换为String对象。
//String--》StringBuilder
String str = "hello";
System.out.println("str:" + str);
StringBuilder bu = new StringBuilder(str);//str:hello
//往StringBuilder中添加数据

bu.append("world");
System.out.println("bu:" + bu);//bu:helloworld

//StringBuilder--》String
String s = bu.toString();
System.out.println("s:" + s);//s:helloworld

包装类

概念

  • 基本数据类型的数据,使用起来非常的方便,但是没有对应的方法来操作这些数据,所以我们可以使用一个类,把基本类型的数据包装起来,这个类叫包装类。
  • 在包装类中定义一些方法,用来操作基本数据类型。

装箱和拆箱

装箱:把基本类型的数据,包装到包装类中。
构造方法:

  • Integer(int value):构造一个新分配的Integer对象,它表示指定的int值。
  • Integer(String s):构造一个新分配的Integer对象,它表示String参数所指示的int值。

静态方法:

  • static Integer valueOf(int i):返回一个表示指定的int值的Integer实例。
  • static Integer valueOf(String s):返回保存指定的String的值的Integer对象。

拆箱:在包装类中取出基本类型的数据。
成员方法:

  • int intValue():以int类型返回该Integer的值。

例如:

Integer in1 = new Integer(value:1);// 方法上有横线,说明方法已经过时了
System.out.println(in1);//1

Integer in2 = new Integer(s:"1");
System.out.println(in2);//1

//静态方法
Integer in3 = Integer.valueOf(1);
System.out.println(in3);//1

Integer in4 = Integer.valueOf(1);
System.out.println(in4);//1

//拆箱
int i = in1.intValue();
System.out.println(i);//1

自动装箱与自动拆箱

//自动装箱
Integer in = 1;
//自动拆箱
in = in + 2;

基本类型与字符串类型之间的转换

基本类型–》字符串:
1.基本类型数据的值+""(最简单)
2.使用包装类的静态方法
static String toString(int i):返回一个表示指定整数的String对象。
3.使用String类中的静态方法
static String valueOf(int i):返回int参数的字符串表示形式。
字符串–》基本类型:
使用包装类的静态方法parseXX
Inter类:static int parseInt(String s)
Double类:static double parseDouble(String s)

//基本类型--》字符串
String s1 = 100 + "";
System.out.println(s1 + 200);//100200

String s2 = Inter.toString(i:100);
System.out.println(s2 + 200);//100200

//字符串--》基本类型
int i = Integer.parseInt(s:"100");
System.out.println(i + 200);//300
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值