第六周笔记

1. 内部类

如果一个事物内部包含另一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。

分类:

  1. 成员内部类。
  2. 局部内部类(包含匿名内部类)。

1.1 成员内部类的定义

定义格式:

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

注意: 内用外,随便访问,外用内,需要一个内部类的成员对象。

//外部类
public class Body {
	//成员内部类
	public class Heart {
		//内部类的方法
		public void beat() {
			System.out.println("心脏蹦蹦跳!");
			System.out.println("name");
		}
	}
	//外部类的成员变量
	private String name;
	//外部类的方法
	public void methodBody() {
		System.out.println("外部类的成员变量");
		Heart heart = new Heart();
		heart.beat();
	}
	public String getName() {
		return name;
	}
	public void setName() {
		this.name = name;
	}
}

1.2 成员内部类的使用

  1. 间接方法:在外部类的方法当中,使用内部类,然后main只是调用外部类的方法。
  2. 直接方式:
    格式: 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
public class InnerClass {
	public static void main(String[] args) {
		Body body = new Body();   //创建外部类对象
		//通过外部类的对象,调用外部类的方法,立面间接使用内部类Heart
		body.methodBody;

		//直接方法
		Body.Heart heart = new Body().new Heart();
		heart.beat();
	}
}

1.3 内部类的同名变量访问

如果出现了重名,格式为:外部类名称.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
		}
	}
}

1.4 局部内部类定义

如果一个类是定义在一个方法内部的,那么它就是局部内部类。
“局部”,只有当前所属的方法才能使用它,出了这个方法就不能使用了。

定义格式:

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

例:

public class Outer {
	public void methodOuter() {
		//局部内部类
		class Inner {
			int num = 10;
			public void methodInner() {
				System.out.println(num); //10
			}
		}
		Inner inner = new Inner();
		inner.methodInner;
	}
}

使用:

public class DemoMain {
	public static void main(String[] args) {
		Outer outer = new Outer();
		outer.methodOuter();
	}
}

类的修饰符:public > protected > (default) > private
定义一个类的时候,权限修饰符规则:

  1. 外部类:public / (default)
  2. 成员内部类:public / protected / (default) / private
  3. 局部内部类:什么都不能写

1.5 局部内部类的final问题

局部内部类如果希望访问所在方法的局部变量,那么这个局部变量必须是 有效final的
从Java 8开始,只要局部变量事实不变,那么final关键字可以省略。

原因:

  1. new出来的对象在堆内存当中。
  2. 局部变量是跟着方法走的,在栈内存中。
  3. 方法运行结束后,立刻出栈,局部变量就会立刻消失。
  4. new出来的对象会在堆中持续存在,知道垃圾回收消失。

1.6 匿名内部类

如果接口的实现类(或者父类的子类)只需要使用唯一的一次。那么就可以省略掉该类的定义,而改为使用【匿名内部类】;

匿名内部类的定义格式:

接口名称 对象名 = new 接口名称(){
	//覆盖重写所有的抽象方法
};

例:

public class DemoMain {
	public static void main(String[] args){
		MyInterface obj = new MyInterface() {
			@Override
			public void method() {
				System.out.println("匿名内部类实现了方法");
			}
		};
		obj.method();
		//如果该实现类对象只使用一次
		new MyInterface() {
			@Override
			public void method() {
				System.out.println("匿名内部类实现了方法");
			}
		}.method();
	}
}

1.7 匿名内部类的注意事项

对格式“new 接口名称(){…}”进行解析:

  1. new代表创建对象的动作;
  2. 接口名称就是匿名内部类需要实现的那个接口;
  3. {…}才是匿名内部类的内容;
  4. 匿名内部类,在创建对象的时候,只能使用唯一一次。
    如果希望多次创建对象,而且类的内容一样的话,那么就必须单独定义的实现类了。
  5. 匿名对象,在调用方法的时候,只能调用唯一一次。
    如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
  6. 匿名内部类是省略了【实现类/子类名称】,匿名对象省略了【对象名称】。

2. Object类和Objects类

  • java.lang.Object类是Java语言中的根类,即所有类的父类。
  • 如果一个类没有特别指定父类,那么默认Object为父类。

2.1 Object类的toString方法

格式: 对象名.toString();
作用: 返回该对象的地址值,返回值为String类型。
注意: 直接打印对象的名字,其实就是在调用对象的toString方法

String s = p.toString();
System.out.println(s);
//作用一样
System.out.println(p);

2.2 toString方法的覆盖重写

重写toString方法,使它返回对象的属性

public class Person {
    String name;
    int age;

    public Person() {
    }

    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 Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class DemoToString {
    public static void main(String[] args) {
        Person p = new Person("张三", 18);
        System.out.println(p.toString());    //Person{name='张三', age=18}
    }
}

注意: 看一个类是否重写了toString方法直接打印这个类对应的对象名称即可;若没有重写,那么打印的就是该对象的地址值。

2.3 Object类的equals方法

格式: 对象名1.equals(对象名2);
作用: 比较两对象是否“相等”,返回值为boolean类型;
注意: 比较的是两对象的地址值。

public class DemoEquals{
	public static void main(String[] args){
		Person p1 = new Person("张三", 18);
		Person p2 = new Person("李四", 17);

		boolean b = p1.equals(p2);
		System.out.println(b); //false
	}
}

2.4 equals方法覆盖重写

重写equals方法,使它比较两对象的属性

......
@Override
    public boolean equals(Object obj) {
    	//若obj为null,直接返回false,提高程序效率
    	if(obj == null){
			return false;
		}
		//若obj就是this,直接返回true
		if(obj == this){
			return true;
		}
    	//向下强制类型转换
    	if(obj instanceof Person){
        	Person p = (Person)obj;
        	boolean b = p.name.equals(this.name) && p.age == p.age;
        	return b;
        }
        //若obj不是Person类型的,直接返回false
        return false;
    }
......

可以Alt + Insert快捷键直接生成

......
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
......

2.5 Objects类的equals方法

格式: Objects.equals(对象名1, 对象名2);
作用: 对两个对象进行比较,防止空指针异常,返回值为boolean类型。
原理:

public static boolean equals(Object a, Object b){
	return (a == b) || (a != null && a.equals(b));
}

注意: 需要导包 import java.util.Objects;

import java.util.Objects;
public class DemoObjects {
	public static void main(String[] args){
		String s1 = "abc";
		String s2 = "abc";
		boolean b = Objects.equals(s1, s2);
		System.out.println(b); //true
	}
}

3. 日期时间类

3.1 毫秒值的概念和作用

  • java.util.Date;表示日期和时间的类,需要导包。
  • 类Date表示特点的瞬间,精确到毫秒。
  • 毫秒:千分之一秒;
  • 毫秒值的作用:可以对时间和日期进行计算(把日期转化成毫秒,计算完再把毫秒转换成日期)
  • 时间原点(0毫秒):1970年1月1日00:00:00(英国格林威治时间)
  • 注意:中国位于东八区,会把时间增加8小时(即1970年1月1日08:00:00)

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

Date类的空参数构造方法:
Date()获取的是当前系统的日期和时间;
格式: Date 对象名 = new Date();

Date类的带参数构造方法:
Date(long date)传递毫秒值,把毫秒值转换为Date日期
注意: 毫秒值后加L
格式: Date 对象名 = new Date(毫秒值L);

Date类的成员方法:
long getTime();把日期转化成毫秒(相当于System.currentTimeMillis());
返回自1970.1.1 00:00:00 GMT以来此Date对象表示的毫秒值。
格式: long 对象名 = 对象名.getTime();

import java.util.Date;

public class DemoDate {
    public static void main(String[] args) {
        demo01();
        demo02();
        demo03();
    }
    public static void demo01(){
        Date date = new Date();
        System.out.println(date);
    }
    public static void demo02(){
        Date date = new Date(12345L);
        System.out.println(date);
    }
    public static void demo03(){
        Date date = new Date();
        long time = date.getTime();
        System.out.println(time);
    }
}

3.3 DateFormat类 & SimpleDateFormat类介绍

java.text.DateFormat; 是日期时间格式化子类的抽象类

作用:

  1. 格式化:把日期变成文本;
  2. 解析:把文本变成日期。

成员方法:

  1. String format(Date date);按照指定的模式,把Date日期,格式化为符合模式的字符串;
  2. Date parse(String source); 把符合模式的字符串解析为Date日期

DateFormat类是一个抽象类,无法直接创建对象使用,可以使用DateFormat的子类

java.text.SimpleDateFormat extends DateFormat;

构造方法:
SimpleDateFormat(String pattern) 用给定模式和默认语言环境的日期格式符号构建SimpleDateFormat

参数: String pattern 传递指定的模式
模式: 区分大小写

yM
dH
ms

“yyyy-MM-dd HH:mm:ss”
“yyyy年MM月dd日 HH时mm分ss秒”

注意事项: 模式中的字母不能更改,连接模式的符号可以改变。

3.4 DateFormat类的farmat方法和parse方法

farmat方法

使用步骤:

  1. 创建SimpleDateFormat对象,构造方法中传递指定的模式。
  2. 调用SimpleDateFormat对象中的方法farmat,按照构造方法中指定的模式把Date日期格式化为符合模式的字符串文本。
parse方法

使用步骤:

  1. 创建SimpleDateFormat对象,构造方法中传递指定的模式;
  2. 调用SimpleDateFormat对象中的方法parse,把符合构造方法中模式的字符串解析为Date日期。

注意事项:
public Date parse(String source) throws ParseException

  • parse方法声明了一个异常叫ParseException解析异常;
  • 如果字符串和构造方法中的模式不一样,那么程序就会抛出该异常;
  • 调用一个抛出了异常的方法,就必须处理这个异常,要么throws继续声明抛出这一个异常,要么try…catch自己处理这个异常(快捷键Alt+Enter)。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DemoDateFormat {
    public static void main(String[] args) throws ParseException {
        demo1();
        demo2();
    }

    public static void demo1() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String text = sdf.format(date);
        System.out.println(text);  //2020-05-09 23:01:40
        System.out.println(date);  //Sat May 09 23:01:40 CST 2020
    }

    public static void demo2() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        Date date = sdf.parse("2020年10月11日 10时11分12秒");
        System.out.println(date);  //Sun Oct 11 10:11:12 CST 2020
    }
}

3.5 Calendar类介绍

java.util.Calendar; 是日历类,方便获取各个时间属性的。

  • Calendar类是一个抽象类里面提供了很多操作日历字段的方法(YEAR, MONTH, DAY_OF_MONTH, HOUR)。
  • Calendar类无法直接创建对象使用,它有一个静态方法getInstance(),该方法返回Calendar类的子类对象。
  • static Calendar getInstance(); 使用默认时区和语言环境获得一个日历。

3.6 Calendar类的常用成员方法

  • public int get(int field): 返回给定日历字段的值。
  • public void set(int field, int value): 将给定的日历字段设置为给定值
  • public abstract void add(int field, int amount): 根据日历的规则,为给定的日历段添加或删去指定的时间量。
  • public Date getTime(): 返回一个表示Calendar时间值(从历元到现在的毫秒偏移量)的Date对象,把日历转换为日期。

成员方法的参数:

  1. field:日历段的字段,可以使用Calendar类的静态成员变量获取
  2. public static final int YEAR = 1; 年
  3. public static final int MONTH = 2; 月
  4. public static final int DATE = 5; 月中的某一天
  5. public static final int DAY_OF_MONTH = 5; 月中的某一天
  6. public static final int HOUR = 10; 时
  7. public static final int MINUTE = 12; 分
  8. public static final int SECOND = 12; 秒
import java.util.Calendar;
import java.util.Date;

public class DemoCalendar {
    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        System.out.println(c);

        demo1();
        demo2();
        demo3();
        demo4();
    }

    public static void demo1() {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH); //西方的月份0-11
        int date = c.get(Calendar.DATE);
        System.out.println(year + "," + month + "," + date);
    }

    public static void demo2() {
        Calendar c = Calendar.getInstance();
        //将年改为3030年
        c.set(Calendar.YEAR, 3030);
        //可同时设置年月日
        c.set(3030, 3, 3);
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int date = c.get(Calendar.DATE);
        System.out.println(year + "," + month + "," + date);  //3030,3,3
    }

    public static void demo3() {
        Calendar c = Calendar.getInstance();
        //增加两年
        c.add(Calendar.YEAR, 2);
        //减少三月
        c.add(Calendar.MONTH, -3);
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        System.out.println(year + "," + month);
    }

    public static void demo4() {
        Calendar c = Calendar.getInstance();
        Date date = c.getTime();
        System.out.println(date);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值