背诵--2
DAY01 面向对象回顾、继承、抽象类
学习目标
能够写出类的继承格式
public class 子类 extends 父类{}
public class Cat extends Animal{}
能够说出继承的特点
子类继承父类,就会自动拥有父类非私有的成员
能够说出子类调用父类的成员特点
1.子类有使用子类自己的
2.子类没有使用,继承自父类的
3.子类父类都没有编译报错
能够说出方法重写的概念
发生在两个类之间
子类出现了和父类一模一样(返回值类型,方法名,参数列表,修饰符子类大于等于父类)的方法,叫方法重写(Override)
能够说出this可以解决的问题
1.this.变量名:代表本类的成员变量
2.this.方法名称():代表本类的成员方法
3.this(),this(参数):代表调用本类其他的构造方法
能够说出super可以解决的问题
1.super.变量名:代表父类的成员变量
2.super.方法名称():代表父类的成员方法
3.super(),super(参数):代表调用父类的构造方法
描述抽象方法的概念
没有方法体,被abstract修饰的方法
写出抽象类的格式
public abstract class 类名{};
写出抽象方法的格式
权限修饰符 abstract 返回值类型 方法名(参数);
public abstract void aaa();
public abstract int bbb();
public abstract int ccc(String s);
能够说出父类抽象方法的存在意义
在抽象类中定义类抽象方法,那么子类就必须重写这个抽象方法
公司中所有的员工都必须工作
作为模版:让子类强制重写抽象方法,不同的子类添加不同的方法体
this关键字
/*
this关键字:
代表本类对象的引用==>根据类创建的对象
哪个对象调用的方法,方法中的this就是哪个对象
this关键字作用:当局部变量和成员变量重名时,使用this关键字可以区分局部变量和成员变量
this.变量名==>成员变量
*/
对象的内存图
匿名对象
package com.itheima.demo03Object;
import java.util.ArrayList;
/*
匿名对象:
创建对象时,只有创建对象的语句,没有把对象赋值给某个变量,这个对象叫匿名对象
没有名字的对象
特点:
只能使用一次,使用完毕会被JVM在空闲的时候进行垃圾回收
好处:
可以节约内存,可以提高程序的效率
作用:
一般可以作为方法的参数和返回值使用
*/
public class Demo01Animal {
public static void main(String[] args) {
//创建一个有名字的对象:可以重复使用
Animal a1 = new Animal("Tom");
a1.eat();
a1.eat();
//创建一个匿名对象:只能使用一次
new Animal("Jerry").eat();
//如果想要在使用匿名对象,需要重新创建
new Animal("熊大").eat();
System.out.println("---------------------------");
//调用show方法,创建Animal对象为变量a2赋值
show(a1);
//如果方法的参数传递的对象只使用一次,就可以使用匿名对象
show(new Animal("熊二"));
System.out.println("----------------------------");
//调用getAnimal方法
//Animal a4 = getAnimal();==> new Animal("光头强");
Animal a4 = getAnimal();
a4.eat();
System.out.println("----------------------------");
ArrayList<Animal> list = new ArrayList<>();
list.add(a1);
//对象只使用一次,就可以使用匿名对象
list.add(new Animal("加菲猫"));
}
/*
定义一个方法,方法的参数使用Animal类型
Animal a2 = a1 = new Animal("Tom");
Animal a2 = new Animal("熊二")
*/
public static void show(Animal a2){
a2.eat();
}
/*
定义一个方法,方法的返回值类型使用Animal
方法的返回值类型是Animal,就必须在方法中创建一个Animal对象返回
方法的返回值类型是int,就必须在方法中返回一个整数
...
*/
public static Animal getAnimal(){
//Animal a3 = new Animal("光头强");
//return a3;
//对象只使用一次,就可以使用匿名对象
return new Animal("光头强");
}
}
继承
继承的概念:子类继承父类,子类就会自动拥有父类非私有的成员变量和成员方法。
继承的特点:
子类继承父类,子类就会自动拥有父类非私有的成员变量和成员方法
在子类中可以定义子类特有的成员
继承的注意事项:
1.构造方法是不能继承的,构造方法是本类创建对象使用的
2.父类私有成员子类是不能继承的
继承后的特点—成员变量:
1.子类有使用子类自己的成员变量
2.子类没有使用子类继承自父类的成员变量
3.子类和父类都没有,编译报错
继承后的特点—成员方法:
1.子类有使用子类自己的成员方法
2.子类没有使用子类继承自父类的成员方法
3.子类和父类都没有,编译报错
方法重写
/*
方法重写:发生在两个类之间,在子类中出现了和父类一模一样的方法,叫方法重写(Override)
一模一样:
方法名一样
参数列表一样
返回值类型一样
修饰符一样(子类的修饰符权限大于等于父类的修饰符)
注解:
@Override:检查方法是否为重写的方法
------------------------------------------------------------
方法重载:发生在一个类中,在一个类中出现了方法名相同,但是参数列表不同的方法,叫方法重载(Overload)
*/
this和super
/*
继承后的特点—构造方法
在子类构造方法的第一行,有一个默认的super();
super();作用就是调用父类的空参数构造方法
子类继承父类,子类想要使用继承自父类的成员,就必须把父类加载到内存中,调用父类的构造方法创建父类对象
父类进入到内存中,子类才可以使用父类的成员
*/
/*
this关键字:本类对象的引用(根据Cat创建的对象)
this.成员变量:本类的成员变量
this.成员方法(参数):本类的成员方法
super关键字:父类对象的引用(根据Animal创建的对象)
super.成员变量:父类的成员变量
super.成员方法(参数):父类的成员方法
*/
/*
this关键字:可以调用本类其他的构造方法
格式:
this();调用空参数构造方法
this(参数);调用带参数构造方法
注意:
1.this();|this(参数);调用构造方法必须写在构造方法中的第一行,创建对象必须优先执行
2.构造方法不能相互调用(不能你调用我,我在调用你-->死循环)
*/
/*
super关键字:调用父类的构造方法
格式:
super();调用父类的空参数构造方法
super(参数);调用父类带参数构造方法
注意:
1.在子类的构造方法中没有写super();有一个默认的super();用于调用父类的空参数构造方法
2.super();|super(参数);必须写在子类构造方法有效代码的第一行,构造方法必须优先执行
3.在子类的构造方法中this和super不能同时出现,都必须写在有效代码第一行
*/
DAY02 final关键字、static关键字、接口
学习目标
描述final修饰的类的特点
//是一个最终类不能被继承,是一个太监类
描述final修饰的方法的特点
//是一个最终方法,可以被继承使用,但是不能被重写
描述final修饰的变量的特点
//是一个常量,值不能改变
局部变量:定义在方法中的变量
基本数据类型:值不能改变
引用数据类型(数组,对象,集合...):地址值不能改变
成员变量:定义在成员位置,类中方法外
保证在创建对象前赋值
1.可以定义变量的时候直接赋值
2.可以使用构造方法给变量赋值
能够掌握static关键字修饰的变量调用方式
类名.静态成员变量
public class Person{
static int a = 10;
}
Person.a;
能够掌握static关键字修饰的方法调用方式
类名.静态成员方法(参数);
public class Person{
public static void show(int a){}
}
Person.show(10);
能够写出接口的定义格式
public interface 接口名{
抽象方法 public abstract 返回值类型 方法名(参数);
默认方法 public default 返回值类型 方法名(参数){方法体}
静态方法 public static 返回值类型 方法名(参数){方法体}
}
能够写出接口的实现格式
public class 实现类 implements 接口{}
能够说出接口中的成员特点
变量:接口中的变量都是常量,有固定的修饰符 public static final int AAA = 10;
方法:抽象方法(需实现类重写) 默认方法(实现类可以选择性重写) 静态方法(不能重写,使用接口名直接调用)
接口中没有构造方法,不能创建对象
final关键字
/*
final修饰的类:是一个最终类,不能被继承;其他的使用方式不变(继承其他的类,创建对象使用...)
简单记:太监类
*/
/*
final修饰的方法:是一个最终方法,可以被继承使用,但是不能被重写
*/
/*
final修饰的变量:是一个常量,值不能改变
局部变量:定义在方法中的变量(语句中for)
final修饰符是局部变量唯一的修饰符
引用数据类型(数组,类,集合...):地址值不能改变
对象中的内容是可以改变的(成员变量的值,数组中的元素,集合中的元素...)
*/
/*
final修饰的成员变量:是一个常量,值不能改变
特点:特殊记忆
final修饰的成员变量必须在创建对象前赋值(规定)
注意:
1.成员变量的默认值(String=>null,int==>0,doble=>0.0,boolean==>false),不是final修饰的成员变量的值,必须赋一个具体值
2.赋值的方式:
a.直接赋值:定义变量,直接给变量赋值
b.使用构造方法赋值,构造方法是创建对象前执行
无论哪种赋值方式,只能赋值一次
3.常量的命名规则:一般都使用大写字母
final int AAA_BBB_CCC = 10;
*/
public class Student {
//final int a;//Variable 'a' might not have been initialized
//a.直接赋值:定义变量,直接给变量赋值
final int b = 10;
final int c;
final String d = null;
//b.使用构造方法赋值,构造方法是创建对象前执行
public Student() {
c = 20;
//b = 100;//Cannot assign a value to final variable 'b' 无论哪种赋值方式,只能赋值一次
}
public Student(int e){
c=e;
}
}
static关键字
接口
接口:是引用数据类型的一种,是功能的集合(接口中定义的都是方法)
接口中不能定义变量,可以定义常量(很少使用)
定义接口使用的也是.java文件;编译生成的也是.class文件
定义接口使用关键字interface
定义格式:
修饰符 interface 接口名{
抽象方法;(jdk7)重点
默认方法;(jdk8)
静态方法;(jdk8)
}
/*
接口的多实现:类可以同时实现多个接口
格式:
public class 实现类 implements 接口1,接口2,接口3....接口n{
重写所有接口中的抽象方法
}
注意:
接口中含有抽象方法,实现类需要重写所有接口的抽象方法
如果接口中有同名的抽象方法,实现类只重写一个就可以了
不会产生不确定性,抽象方法没有方法体
*/
/*
接口的多实现:类实现含有默认方法的多个接口
格式:
public class 实现类 implements 接口1,接口2,接口3....接口n{
}
注意:
1.如果接口中的默认方法不重复,实现类可以选择重写或者不重写默认方法
重写:使用实现类重写的
不重写:使用继承自接口的
2.如果多个接口中默认方法有重复的,实现类必须重写这个重复的默认方法
有不确定性,实现类不知道使用继承自哪个接口的默认方法,重写之后使用自己的
*/
/*
接口的多实现:实现类实现含有静态方法的多个接口
格式:
public class 实现类 implements 接口1,接口2,接口3....接口n{
}
注意:
1.实现类实现含有静态方法的接口,没有意义;静态方法实现类不能继承,也不能重写
2.接口中静态方法有重复的,不会冲突,静态方法属于每个接口本身
*/
/*
接口中其他成员的特点(使用)
1.接口中是无法定义成员变量的,但是可以定义常量,常量的值不能改变
默认使用的修饰符public static final,接口中的常量修饰符可以省略不写,默认默认也是public static final
常量的命名规则:所有的单词都要大写,多个单词之间使用下划线连接
AAA_BBB_CCC
定义一些常用的常量:
公司的名称:"江苏省传智播客股份有限公司北京分公司"
公司的网址: www.itcast.cn www.itheima.com
公司地址: 昌平区建材城西路金燕龙办公楼一层
2.接口中,没有构造方法,不能创建对象
3.接口中,没有静态代码块(讲代码块的时候在说)
*/
DAY03 多态、内部类、权限修饰符、代码块
学习目标
能够说出多态的前提
//有子父类继承关系|有类和接口的实现关系
能够写出多态的格式
//父类的类型 变量名 = new 子类对象();
Animal a = new Cat();
Animal a = new Dog();
//接口的类型 变量名 = new 实现类对象();
Fly f = new MaQue();
能够理解多态向上转型和向下转型
//向上转型:多态本身就是向上转型
格式:
父类的类型 变量名 = new 子类对象();
接口的类型 变量名 = new 实现类对象();
Animal a = new Cat();
a = new Dog();
好处:
扩展性强,可以赋值不同的子类对象,调用不同子类重写的方法
弊端:
无法使用子类特有的成员变量和成员方法
//向下转型:前提必须是多态,可以把父类的类型强制转换为子类类型
格式:
子类类型 变量名 = (子类类型)父类变量名;
Cat c = (Cat)a;
c.catchMouse();
好处:
可以使用子类特有的内容
能够说出内部类概念
//把类定义在其他类的内部
成员内部类:类定义在其他类的成员位置
局部内部类:类定义在其他类的方法中
注意:局部位置唯一可以使用的修饰符就是final
能够理解匿名内部类的编写格式(new 爹(亲爹父类,干爹接口))
作用:简化代码
把子类继承父类,重写父类的方法,创建子类对象合成一步完成;
把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成;
格式:
new 父类|接口(){
重写父类|接口中方法;
};
new Animal(){
public void eat(){}
public void sleep(){}
}.eat();
new Fly(){
public void fly(){}
}.fly();
能够说出每种权限修饰符的作用
private:只能在本类中使用
默认(不写):既能在本类中使用,又能在本包的其他类中使用
protected:既能在本类中使用,又能在本包的其他类中使用,还能在不同包的子类中使用
public:本项目中的任意包,任意的类中都可以使用
需要记住(重点):
1.privare使用:定义成员变量,需要私有(封装)
2.public使用:定义成员方法,定义构造方法,定义类
代码块:
静态代码块:只执行一次,优先执行
多态
/*
多态的转型:
1.向上转型:多态本身就是向上转型,把子类对象赋值给父类的变量
格式:
父类类型 变量名 = new 子类对象():
好处:
扩展性强,可以赋值不同的子类对象,而调用不同子类重写后的方法
--------------------------------------------------------------
int a = 10;
double d = a;
2.向下转型:把父类类型的变量强制转换为子类类型(强转)
格式:
子类类型 变量名 = (子类类型)父类变量名;
好处:
强制之后,多态变量变成了子类类型,就可以使用子类特有的功能
注意:
a.向下转型前提,必须是多态
b.直接创建父类对象,不能向下转型
-----------------------------------------------------------------
double d = 5.5;
int a = (int)d;
*/
/*
向下转型:有可能发生类型转换异常
ClassCastException: com.itheima.demo02duotai.Cat cannot be cast to com.itheima.demo02duotai.Dog
猫不能转换为狗
instanceof关键字:判断某个对象是否属于某种数据类型
格式:
boolean b = 对象 instanceof 数据类型;
对象属于对应的数据类型,返回true
对象不属于对应的数据类型,返回false
使用前提:
对象根据类创建的(对象所属的类和判断的数据类型之间必须有继承或者实现关系)
*/
内部类
/*
内部类:定义在其他类内部的类
分类:
成员内部类:内部类定义在其他类的成员位置(类中方法外)
局部内部类:内部类定义在其他类的方法中
重点:记住固定格式
---------------------------------------------------------------
成员内部类:
定义格式:
修饰符 class 外部类{
修饰符 class 成员内部类名{
内部类的成员变量
内部类的成员方法
}
}
使用格式:通过外部类来找到内部类
外部类名.内部类名 变量名 = new 外部类().new 内部类();
变量名.内部类的成员变量
变量名,内部类的成员方法();
注意:
1.在内部类中可以直接使用外部类的成员变量和成员方法
2.内部类只是定义在其他类的内部,其他的使用方式不变,也可以继承其他的类,也可以实现接口
*/
注意:内部类生成的class文件含有$
/*
局部内部类:定义在其他类的方法中
定义格式:
修饰符 class 外部类名{
修饰符 返回值类型 外部类方法名(参数){
(final)class 局部内部类名{
内部类的成员变量,
内部类的成员方法();
}
}
}
使用格式:局部内部类的使用范围就是在方法中有效
使用方式就是在方法中定义完局部内部类之后,直接创建局部内部类对象使用
*/
public class Outer {
//定义一个外部类的成员方法
public void show01(){
//定义局部内部类(局部变量唯一可以使用的修饰符final 面试)
final class Inner{
//定义局部内部类的成员变量
int a = 10;
//定义局部内部类的成员方法
public void inner(){
System.out.println("局部内部类Inner的成员方法inner!");
}
}
//定义完局部内部类之后,直接创建局部内部类对象使用
Inner in = new Inner();
System.out.println(in.a);
in.inner();
//final int aa = 10;
//System.out.println(aa);
}
//定义一个外部类的成员方法
public void show02(){
//定义局部内部类(局部变量唯一可以使用的修饰符final 面试)
final class Inner{
//定义局部内部类的成员变量
int a = 10;
//定义局部内部类的成员方法
public void inner(){
System.out.println("局部内部类Inner的成员方法inner!");
}
}
//定义完局部内部类之后,直接创建局部内部类对象使用
Inner in = new Inner();
System.out.println(in.a);
in.inner();
//final int aa = 10;
//System.out.println(aa);
}
}
注意:局部内部类生产的class含有$(1,2,3指的是外部类中第1个,第2个…方法)
/*
匿名内部类(重点):
匿名:创建内部类,不像Cat.Dog有类名,没有具体的类名
内部类:是一个局部内部类(写在方法中)
作用:简化代码
把子类继承父类,重写父类的方法,创建子类对象合成一步完成
把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成
格式:
new 父类|接口(){
重写父类|接口中的方法;
};
------------------------------------------------
new Animal(){
@Override
public void eat() {
System.out.println("动物在吃饭");
}
@Override
public void sleep() {
System.out.println("动物在睡觉!");
}
};
以上一堆代码就是一个创建子类对象的过程,相当于new Cat();
*/
权限修饰符
public | protected | default(空的) | private | |
---|---|---|---|---|
同一类中 | √ | √ | √ | √ |
同一包中(子类与无关类) | √ | √ | √ | |
不同包的子类 | √ | √ | ||
不同包中的无关类 | √ |
代码块
public class Student {
private String name;
private int age;
private static String sex;
/*
2.构造代码块:写在成员位置(类中方法外)的代码块
特点:
优先于构造方法执行,每创建一次对象,都会执行一次
作用:
1.可以给成员变量赋初始化值
2.可以把每个构造方法中的共性内容提取出来,写在构造代码块中,可以提高代码复用性
需求:无论使用空参数|带参数构造方法创建对象,都先打印10次HelloWorld
*/
{
//1.可以给成员变量赋初始化值
name = "张三";
age = 18;
System.out.println("构造代码块!");
//2.可以把每个构造方法中的共性内容提取出来,写在构造代码块中
/*for (int i = 1; i <=10 ; i++) {
System.out.println("HelloWorld"+i);
}*/
}
/*
3.静态代码块:写在成员位置(类中方法外)被static修饰的代码块
特点:
static修饰的成员属于类,不属于某一个对象,被所有的对象所共享
所以我们无论创建多少次对象,静态代码块只执行一次
静态优先于非静态加载到内存中,优先于构造代码块和构造方法执行
作用:
1.可以给静态的成员变量赋初始化值
2.在项目启动的时候,可以做一些初始化的设计(只执行一次 数据库)
*/
static {
sex = "男";
System.out.println("静态代码块!");
}
public Student() {
/*for (int i = 1; i <=10 ; i++) {
System.out.println("HelloWorld"+i);
}*/
System.out.println("Student类的空参数构造方法!");
}
public Student(String name, int age) {
/*for (int i = 1; i <=10 ; i++) {
System.out.println("HelloWorld"+i);
}*/
this.name = name;
this.age = age;
System.out.println("Student类的带参数构造方法!");
}
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 static String getSex() {
return sex;
}
public static void setSex(String sex) {
Student.sex = sex;
}
}
/*
代码块:被{ }包裹起来的代码叫代码块
1.局部代码块:写在方法中的代码块
2.构造代码块:写在成员位置(类中方法外)的代码块
3.静态代码块:写在成员位置(类中方法外)被static修饰的代码块
*/
public class Demo01 {
public static void main(String[] args) {
/*
1.局部代码块:写在方法中的代码块
作用:修改变量的作用域,提高程序的效率
变量的作用域:在变量所在的{ }的范围内有效,出了作用域,就会被垃圾回收
*/
{
int a = 10;
//System.out.println(a);
}
//System.out.println(a);//Cannot resolve symbol 'a'
//for (int i = 0; i < 10; i++) {
// System.out.println(i);
//}
//System.out.println(i);//Cannot resolve symbol 'i'
Student s1 = new Student();
System.out.println(s1.getName()+"\t"+s1.getAge()+"\t"+s1.getSex());
Student s2 = new Student("柳岩",18);
System.out.println(s2.getName()+"\t"+s2.getAge()+"\t"+s1.getSex());
}
}
DAY04 Object、Date类、DateFormat类、Calendar类、Math类、System类
学习目标
能够说出Object类的特点
是所有类的祖宗类,任意的一个类都直接或者间接的继承了Object类,都可以使用Object类中的方法
Animal extends Object:直接继承
Cat extends Animal:间接继承
能够重写Object类的toString方法
alt+insert,选择toString
能够重写Object类的equals方法
alt+insert,选择equals and hashCode
能够使用日期类输出当前日期
import java.util.Date;
Date date = new Date();
sout(date);//Mon Apr 27 15:55:03 CST 2020
能够使用将日期格式化为字符串的方法
//1.创建SimpleDateFormat对象,构造方法中传递指定的模式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
//2.调用SimpleDateFormat对象中的方法format根据构造方法中传递的模式,把日期格式化为符合模式的字符串
Date date = new Date();
System.out.println(date);//Wed Mar 18 11:50:38 CST 2020
String s = sdf.format(date);
System.out.println(s);// 2020年03月18日 11时51分32秒
能够使用将字符串转换成日期的方法
//1.创建SimpleDateFormat对象,构造方法中传递指定的模式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//2.调用SimpleDateFormat对象中的方法format根据构造方法中传递的模式,把日期格式化为符合模式的字符串
Date date = sdf.parse("2000-12-12");
System.out.println(date);//Tue Dec 12 00:00:00 CST 2000
能够使用Calendar类的get、set、add方法计算日期
int get(int field) 获取给定日历字段的值。
void set(int field, int value) 将给定的日历字段设置为给定值。
void add(int field, int amount) 把日历字段增加|减少指定的值
能够使用Math类对某个浮点数进行四舍五入取整
static double ceil(double a) 向上取整
static double floor(double a) 向下取整
static long round(double a) 四合五入 long。
能够使用System类获取当前系统毫秒值
static long currentTimeMillis() 返回以毫秒为单位的当前时间。
Object类
- java.lang.Object 注意:lang包中的类无需导包可以直接使用
- 类
Object
是类层次结构的根类(最顶层的类 祖宗类)。 - 每个类都使用
Object
作为超类。任何一个类都直接或者间接的继承了Object类 - 所有对象(包括数组)都实现这个Object类的方法。任何一个类都可以使用Object类中的方法
/*
Object类中的常用方法:
String toString() 返回该对象的字符串表示。
Object类toString方法的底层源码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
getClass().getName():使用反射技术获取类的全类名(包名+类名)
com.itheima.demo01toString.Person
"@" :字符串原样输出,分割的作用
hashCode():Object类中的方法,可以获取对象的哈希值,哈希值是一个系统随机给出的十进制的整数 123123123
Integer.toHexString(hashCode());把十进制的整数转换为十六进制 0-9 a-f
组合在一起: com.itheima.demo01toString.Person@AC123(对象在堆内存中的地址值)
*/
/*
Object类中的方法equals:
boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。
Object类中的equals方法的源码:
public boolean equals(Object obj) {
return (this == obj);
}
==:比较运算符
基本数据类型:比较的是值是否相等 10==20
引用数据类型(数组,集合,类Person):比较的是地址值是否相等 @1ac1==@223
*/
@Override
public boolean equals(Object obj) {
/*
如果obj就是this本身,那么就没有比较在强转进行属性的比较,直接返回true,可以提高效率
*/
if(obj == this){
return true;
}
/*
如果obj的值是null,那么直接返回false,可以提高程序的效率
*/
if(obj==null){
return false;
}
/*
ClassCastException: java.util.Random cannot be cast to com.itheima.demo02equals.Student
为了防止类在转换异常,强转之前使用instanceof关键字进行判断
*/
if(obj instanceof Student){
/*
问题:多态==>无法使用子类特有的成员==>需要向下转型
Object obj = s2 = new Student("韦德",38);
*/
Student s = (Student)obj;
//比较this(s1)和s(obj=s2)两个对象的属性name和age
// 詹姆斯 韦德 35 38
boolean b = this.name.equals(s.name) && this.age == s.age;
return b;
}
//obj不是Student,直接返回false
return false;
}
native修饰的方法:说明这个方法不是java语言编写的
调用的是其他语言编写的代码或者操作系统底层的代码,看不到具体的方法
Object:
public native int hashCode();
public final native Class<?> getClass();
Objects对象的工具类(了解)
/*
java.util.Objects类:操作对象的工具类,里边的方法都是静态的
Objects中的方法都是防止空指针异常的
注意:
工具类中的方法一般都是静态的,可以通过类名直接使用
Obejcts工具类中的equals方法
static boolean equals(Object a, Object b) :判断两个对象是否相等,相等返回true,不相等返回false
底层源码:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
*/
Date类
java.util.Date类:用于描述日期和时间的类
类 Date 表示特定的瞬间,精确到毫秒。
1秒=1000毫秒
1 天 = 24 × 60 × 60 = 86400 秒 = 86400*1000 = 86400000毫秒
-----------------------------------------------
时间原点:0毫秒的时间点
1970 年 1 月 1 日 00:00:00 英国格林威治时间(世界标准时间)
中国:东八区 时间+8个小时的时差
1970 年 1 月 1 日 08:00:00
把日期和时间转换为毫秒值:就是时间原点和当前时间的一个差值
当前时间(2020年4月27日11:26:33)-时间原点(1970年1月1日 00:00:00)=把当前时间转换为毫秒值(12312412514312)
毫秒值的作用:用于对时间进行计算
工作:计算两个时间的差值,把时间转换为毫秒值计算
"2020年4月27日11:26:33" - "2019年3月5日12:26:33" = 没法计算
把时间转换为毫秒值,使用毫秒值相减
15888123123123 - 15734324324233 = 324324毫秒==>转换为时间(324324毫秒/1000/60/60/24)天
DateFormat类
java.text.DateFormat类
public abstract class DateFormat extends Format
DateFormat 是日期/时间格式化子类的抽象类==> DateFormat是Format类的子类,DateFormat本身还是一个抽象类
无法直接创建对象使用
作用:
它以与语言无关的方式格式化并解析日期或时间。
格式化(也就是日期 -> 文本)
解析(文本-> 日期)
DateFormat类的成员方法:
String format(Date date) 传递指定的日期,把日期格式化为符合模式的字符串
Date parse(String source) 把符合模式的字符串解析为Date日期
-----------------------------------------------------------------
DateFormat本身还是一个抽象类,无法直接创建对象使用,需要使用DateFormat类的子类创建对象使用
java.text.SimpleDateFormat类 extends DateFormat类
SimpleDateFormat类构造方法
SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
参数:
String pattern:传递日期和时间的模式
在模式中写y代表年
在模式中写M代表月
在模式中写d代表日
在模式中写H代表时
在模式中写m代表分
在模式中写s代表秒
在模式中写S代表毫秒
"yyyy-MM-dd HH:mm:ss" "2020-04-27 11:57:03"
"yyyy/MM/dd HH:mm:ss"
"yyyy年MM月dd日 HH时mm分ss"
注意:
1.表示模式的字母不能改变(y,M...),字母的连接符号可以改变(-,/...)
2.表示模式的字母严格区分大小写
Calendar类
/*
java.util.Calendar类:日历类
我们可以使用Calendar类中的方法获取日历上的字段(年,月,日,时,分,秒...)
我们可以使用Calendar类中的方法修改日历上的字段的值 2020-->2030 4月-->6月
我们可以使用Calendar类中的方法把日历上字段的值增加|减少 2020-5=2015 4月+3月=7月
我们可以使用Calendar类中的方法把日历对象转换为Date日期对象
Calendar 类是一个抽象类,无法直接创建对象使用,在Calendar类中有一个静态方法叫getInstance
获取Calendar类的子类对象
static Calendar getInstance() 使用默认时区和语言环境获得一个日历。
注意:
西方的月份:0-11月
东方的月份:1-12月
西方的星期:星期日-星期六
东方的星期:星期一-星期日
*/
Math类(重点)
/*
java.lang.Math类:数学工具类
Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
Math类中的方法都是静态方法,通过类名.方法名(参数)可以直接使用
Math类中私有了构造方法,不让我们直接创建对象使用 private Math() {}
成员方法:
public static int abs(int a) 获取参数a的绝对值:
public static double ceil(double a) 向上取整 1.1 2.0 1.9 2.0
public static double floor(double a) 向下取整 1.1 1.0 1.99999 1.0
public static long round(double a) 四舍五入取整 5.5 6 5.49999 5
public static double pow(double a, double b) 获取a的b次幂 2^3 2^4
*/
System类(重点)
/*
java.lang.System类
System 类包含一些有用的类字段和方法。它不能被实例化(私有了构造方法)。
里边的方法都是静态的,通过类名.方法名(参数)可以直接使用
成员方法:
public static void exit(int status) 终止当前运行的 Java 虚拟机,非零表示异常终止
public static native long currentTimeMillis() 返回当前时间(以毫秒为单位)
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 数组复制
*/
DAY05 BigInteger类、BigDecimal类、Arrays类、包装类、String类、引用类型
学习目标
能够说出BigInteger可以解决的问题
//可以操作范围超过long类型的整数
//"11111111232131231233333333333333333333333333333"
能够说出BigDecimal可以解决的问题
//用于小数(浮点数)的精确计算
能够使用Arrays类的sort方法
//static void sort(Object[] a) 根据元素的自然顺序对指定对象数组按升序进行排序。
//int[] arr1 = {1,2,3,7,6,4,9,8,10};
//Arrays.sort(arr1);
//[1, 2, 3, 4, 6, 7, 8, 9, 10]
能够使用Arrays类的toString方法
//static String toString(Object[] a) 对数组进行遍历,把数组中的元素组合成一个字符串返回
//String s = Arrays.toString(arr);
能够说出自动装箱、自动拆箱的概念
//在JDK1.5之后,装箱(int-->Integer)与拆箱(Integer-->int)可以自动转换,无需我们调用方法
能够将基本类型转换为对应的字符串
//1+"" 任意的数据类型的值+空字符串,结果都是一个字符串
能够将字符串转换为对应的基本类型
int i = Integer.parseInt("10");
能够说出String类常用方法的功能及使用
//String concat(String str) 将指定字符串连接到此字符串的结尾。 把两个字符串连接到一起 "a"+"b"
//boolean contains(String s) 判断字符串中是否包含指定的字符串;包含返回true,不包含返回false
//boolean endsWith(String suffix) 判断字符串是否以指定的字符串结尾;是返回true,不是返回false
//boolean startsWith(String prefix) 判断字符串是否以指定的字符串开头;是返回true,不是返回false
//int indexOf(String str) 从前往后在字符串中查找另外一个字符串,找到了返回字符串对应的索引,
//int lastIndexOf(int ch) 从后往前在字符串中查找另外一个字符串,找到了返回字符串对应的索引,
//String replace(String target, String replacement) 把大的字符串中所有的目标字符串,替换为新的字符串
//String substring(int beginIndex) 从开始索引beginIndex截取字符串到字符串的末尾
//String substring(int beginIndex, int endIndex) 从开始索引beginIndex到结束索引endIndex截取字符串;包含头,不包含尾
//char[] toCharArray() 将此字符串转换为一个新的字符数组。
//byte[] getBytes() 查询系统默认的编码把字符串转换为字节数组
//String toLowerCase() 把字符串中所有的英文字符转换为小写 "abc123你好"==>"ABC123你好"
//String toUpperCase() 把字符串中所有的英文字符转换为大写 "ABC123你好"==>"abc123你好"
//String trim() 去掉字符串两端的空格 " abc def www "==>"abc def www"
//String[] split(String regex) 根据自定的字符串对字符串进行切割
能够在不同的位置使用引用类型
//引用数据类型和基本数据类型的使用方式是一样的,只是引用数据类型传递都是地址
//可以作为方法的参数 public static void show(Person p){}
//可以作为方法的返回值类型 public static Person getPerson{return new Person()}
//可以作为成员变量 private Person person;
BigInteger类(重点)
java.math.BigInteger 类,不可变的任意精度的整数。如果运算中,数据的范围超过了long类型后,可以使用BigInteger类实现,该类的计算整数是不限制长度的。
BigInteger(String value) 将 BigInteger 的十进制字符串表示形式转换为 BigInteger。超过long类型的范围,已经不能称为数字了,因此构造方法中采用字符串的形式来表示超大整数,将超大整数封装成BigInteger对象。
BigInteger类提供了对很大的整数进行加、减、乘、除的方法,注意:都是与另一个BigInteger对象进行运算。
方法声明 | 描述 |
---|---|
add(BigInteger value) | 返回其值为 (this + val) 的 BigInteger,超大整数加法运算 |
subtract(BigInteger value) | 返回其值为 (this - val) 的 BigInteger,超大整数减法运算 |
multiply(BigInteger value) | 返回其值为 (this * val) 的 BigInteger,超大整数乘法运算 |
divide(BigInteger value) | 返回其值为 (this / val) 的 BigInteger,超大整数除法运算,除不尽取整数部分 |
BigDecimal类(重点)
/*
java.math.BigDecimal类
用于浮点数(小数)的精确计算
以后想进行小数的精确计算,不要使用float和double,使用BigDecimal类
构造方法:
BigDecimal(String val) 将 BigDecimal 的字符串表示形式转换为 BigDecimal。
参数:
String val:传递一个字符类型的小数 "1.1"
成员方法:
加法:BigDecimal add(BigDecimal augend) 返回一个 BigDecimal,其值为 (this + augend)
减法:BigDecimal subtract(BigDecimal subtrahend) 返回一个 BigDecimal,其值为 (this - subtrahend),
乘法:BigDecimal multiply(BigDecimal multiplicand) 返回一个 BigDecimal,其值为 (this × multiplicand),
除法:BigDecimal divide(BigDecimal divisor) 返回一个 BigDecimal,其值为 (this / divisor)
如果无法表示准确的商值(除法除不尽 10/3=3.3333333333333),则抛出 ArithmeticException。
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。
参数:
参数:
divisor - 此 BigDecimal 要除以的值。
scale - 保留的小数位数(2,3,4...) 3.33 3.333
roundingMode - 要应用的舍入模式。
BigDecimal.ROUND_HALF_UP:四舍五入模式 3.66666666==>3.67 3.333333==>3.3
*/
Arrays类(重点)
/*
java.util.Arrays:操作数组的工具类
此类包含用来操作数组(比如排序和搜索)的各种方法。
Arrays类中的方法都是静态的,可以通过类名.方法名(参数)直接使用
Arrays类中的成员方法:
static String toString(Object[] a) 返回指定数组内容的字符串表示形式。
对数组进行遍历,把数组中的元素组合成一个字符串返回
static void sort(Object[] a)
根据元素的自然顺序对指定对象数组按升序进行排序。
*/
包装类
/*
包装类:
基本数据类型的值(int,double,char,boolean...),使用起来很方便,可以直接使用 10 1.1
但是没有相关的方法,可以操作这些基本数据类型的值
所以我们可以使用一个类,把这些基本数据类型的值包裹起来
在类中定义一些方法,用于操作这些基本数据类型的值
这个类叫包装类
基本数据类型:4类8种
byte short int long float double char boolean
基本数据类型对应的包装类: java.lang包
Byte Short Integer Long Float Double Character Boolean
java.lang.Integer类:
Integer 类在对象中包装了一个基本类型 int 的值。
*/
/*
装箱:把基本类型的值装到包装类中 int-->Integer
1.包装类中的构造方法:
Integer(int value) 传递一个整数
Integer(String s) 传递字符串类型的整数
2.包装类中的静态方法:
static Integer valueOf(int i) 传递一个整数
static Integer valueOf(String s) 传递字符串类型的整数
注意:
两个传递字符串的方法,必须传递整数类型的字符串,否则会抛出异常 "123" "aaa"
*/
/*
拆箱:在包装类对象中取出基本类型的值 Integer==>int
Integer类中的方法
int intValue()以 int 类型返回该 Integer 的值。
long longValue() 以 long 类型返回该 Integer 的值。
*/
/*
装箱:基本类型-->包装类
拆箱:包装类-->基本类型
自动装箱和自动拆箱:在JDK1.5以后,装箱和拆箱可以自动进行,不用我们手动转换
*/
//自动装箱:基本数据类型自动转换为Integer类型使用 list.add(1); 相当于 list.add(new Integer(1));
/*
自动拆箱:Integer类型的数据直接可以变成int类型使用
int i = list.get(0); 就相当于 int i = list.get(0).intValue();
*/
/*
基本类型与字符串之间的转换(重点,经常使用)
1.基本数据类型==>字符串
a.基本数据类型的值+"":工作中最常用 1+""--->"1"
b.使用包装类Integer中的静态方法toString
static String toString(int i) 返回一个表示指定整数的 String 对象。
c.使用String类中的静态方法valueOf
static String valueOf(int i) 返回 int 参数的字符串表示形式。
2.字符串类型==>基本数据类型(非常重要)
在每个包装类中都有一个parseXXX方法,可以把字符串格式的基本类型数据的值,转换为基本数据类型
Integer类: static int parseInt(String s)
Double类: static double parseDouble(String s)
...
注意:
1.除了Character类之外,其他所有包装类都具有parseXxx静态方法
2.字符串必须传递基本数据类型的字符串,否则会抛出数字格式化异常 "100" "aaa":异常
*/
DAY06 综合案例
DAY07 Collection、Iterator、泛型、数据结构
学习目标
能够说出集合与数组的区别
数组:
1.是引用数据类型的一种
2.可以存储多个元素
3.数组的长度是固定的 int[] arr1 = new int[10]; int[] arr2 = {1,2,3};
4.数组即可以存储基本类型的数据,又可以存储引用数据类型的数据
int[],double[],String[],Student[]
集合:
1.是引用数据类型的一种
2.可以存储多个元素
3.集合的长度是可以变化的(可以往集合中添加元素,删除集合中的元素)
4.只能存储引用数据类型的数据
ArrayList<int> 错误 ArrayList<Integer> ArrayList<Student>
能够使用Collection集合的常用功能(重点)
public boolean add(E e) : 把给定的对象添加到当前集合中 。
public boolean remove(E e) : 把给定的对象在当前集合中删除。
public boolean contains(Object obj) : 判断当前集合中是否包含给定的对象。
public boolean isEmpty() : 判断当前集合是否为空。
public int size() : 返回集合中元素的个数。
public Object[] toArray() : 把集合中的元素,存储到数组中
public void clear() :清空集合中所有的元素。
能够使用迭代器对集合进行取元素(重点)
//1.创建集合对象,往集合中添加元素
Collection<String> coll = new ArrayList<>();
//Collection<String> coll = new HashSet<>();
coll.add("詹姆斯");
coll.add("姚明");
coll.add("科比");
coll.add("乔丹");
coll.add("艾弗森");
//2.使用Collection接口中的方法iterator,获取迭代器的实现类对象
Iterator<String> it = coll.iterator();
//3.使用迭代器对象Iterator中的方法hasNext和next遍历集合
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
能够使用增强for循环遍历集合和数组(重点)
for(集合|数组中元素的数据类型 变量名: 集合|数组){
sout(变量名);
}
int[] arr = {1,2,3};
for(int i : arr){
sout(i);
}
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
for(String s : list){
sout(s);
}
能够理解泛型上下限
泛型的上限限定: ? extends E ==>传递的未知类型?只能是E的子类或者本身
泛型的下限限定: ? super E ==>传递的未知类型?只能是E的父类或者本身
能够阐述泛型通配符的作用
泛型的通配符: ? 可以接收任意的数据类型
能够说出常见的数据结构
栈,队列,数组,链表,红黑树
能够说出数组结构特点
查询快,增删慢
能够说出栈结构特点
先进后出
能够说出队列结构特点
先进先出
能够说出单向链表结构特点
查询慢,增删快
Collection集合
数组:
1.是引用数据类型的一种
2.可以存储多个元素
3.数组的长度是固定的 int[] arr1 = new int[10]; int[] arr2 = {1,2,3};
4.数组即可以存储基本数据类型的数据,又可以存储引用数据类型的数据 int[] double[] String[] Student[]
集合:
1.是引用数据类型的一种
2.可以存储多个元素
3.集合的长度是可以变化的(添加元素,删除集合中的元素)
4.集合只能存储引用数据类型的数据
ArrayList<int> 错误 ArrayList<Integer> ArrayList<Student> ArrayList<String>正确
Iterator迭代器
/*
迭代器:是一种通用取出集合中元素的方式
迭代器的由来:
集合有很多种,每种集合的数据结构不同(数组,链表,哈希表...),集合取出元素的方式也不同
我们不可能为每种集合都定义一种取出元素的方式,浪费
所以我们可以使用迭代器,是集合通用的取出元素的方式
迭代器的原理:
判断集合中还有没有元素,有就取出来;
再判断集合中还有没有元素,有再取出来;
一直判断到集合中没有元素为止,这种取出元素的方式叫迭代
------------------------------------------------------------------------------------
java.util.Iterator<E>接口:对 collection 进行迭代的迭代器。
Iterator接口的常用方法:
boolean hasNext() 如果仍有元素可以迭代,则返回 true。
判断集合中还没有没有元素;有返回true,没有返回false
E next() 返回迭代的下一个元素。 取出集合中的元素
------------------------------------------------------------------------------------
Iterator是一个接口无法创建对象使用,使用Iterator接口的实现类对象,Iterator接口的实现类对象是每个集合的内部类(了解)
我们可以使用Collection接口中的方法iterator获取迭代器Iterator接口的实现类对象
Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。
注意:
我们无需关注iterator方法返回的是接口的哪个实现类对象,我们只需要会使用Iterator接口来接收这个实现类对象即可(多态)
*/
//注意:迭代器只能使用一次,想要在遍历元素,必须重新获取一个新的迭代器
/*
迭代器的并发修改异常:在使用迭代器遍历集合的过程中,对集合长度进行了修改,迭代器就会抛出并发修改异常
ConcurrentModificationException
注意:
1.并发:遍历和修改同时进行
2.修改:修改集合的长度(添加元素,删除元素)
解决方案:
1.遍历集合的同时,不修改集合的长度
2.Iterator接口有一个子接口叫ListIterator
在ListIterator接口定义了往集合中添加元素的方法
public interface ListIterator<E>extends Iterator<E>
void add(E e) 迭代器中往集合添加元素的方法
void remove() 删除的是next方法取出的元素
注意:
1.如果使用迭代器中的add|remove方法,往集合中添加|删除元素
就相当于集合和迭代器商量好了,可以往集合中添加|删除元素,迭代器就不会抛出并发修改异常了
2.ListIterator迭代器只能遍历List接口下的集合(ArrayList,LinkedList),不能遍历Set接口下的集合(HashSet,LinkedHashSet)
*/
迭代器的实现类是每个集合的内部类(了解)
注意:
增强for循环底层是一个迭代器,所以在使用增强for循环遍历的时候,不能对集合的长度进行修改,否则会抛出并发修改异常
/*
增强for循环(重点)
是JDK1.5之后出现的新特性
使用for循环的方式,对迭代器进行了简化
增强for循环内部就是一个迭代器,对迭代器进行了封装
Collection接口有一个父接口叫Iterable
public interface Collection<E> extends Iterable<E>
java.lang.Iterable<T>接口
实现这个接口允许对象成为 "foreach" 语句的目标。
Collection接口继承了Iterable接口,所以可以使用增强for循环
Collection接口所有的实现类,都可以使用增强for循环(ArrayList,LinkedList,HashSet...)
------------------------------------------------------------
增强for循环的格式:重点
for(集合|数组中元素的类型 变量名 : 集合名|数组名){
sout(变量名);
}
*/
泛型
/*
java中的泛型:是一个伪泛型,在.java文件中有,但是.class文件中没有
*/
/*
使用泛型创建ArrayList集合对象
好处:
1.使用什么泛型就只能存储什么类型的数据;避免向下转型抛出类型转换异常
2.写上泛型存储的是什么类型,取出的就是什么类型,不用向下转型,就可以使用特有的方法
弊端:
1.不能什么类型的数据都存储
*/
/*
不使用泛型创建ArrayList集合对象
好处:
不使用泛型,集合默认的数据类型就是Object类型,可以存储任意数据类型的元素
弊端:
1.不能使用元素特有的方法(多态)
2.在进行向下转型的时候,容易引发类型转换异常
*/
通过反编译软件,查看的class文件中,没有泛型
/*
定义和使用含有泛型的类:模拟ArrayList集合
当我们不知道使用什么类型的时候,就可以使用泛型,是一个未知的数据类型
可以给泛型赋值任意的数据类型:Integer,Student,Person,String...
定义格式:
public class 类名<泛型>{
类中使用数据类型的地方,都可以使用类上定义好的泛型
}
什么时候确定类上泛型的数据类型
创建对象的时候,确定类上泛型的数据类型;对象使用什么类型,类的泛型就是什么类型
*/
public class GenericClass<C> {
private C name;
public C getName() {
return name;
}
public void setName(C name) {
this.name = name;
}
}
/*
定义和使用含有泛型的方法(重点)
泛型需要定义在方法的修饰符和返回值类型之间
定义格式:
修饰符 <泛型> 返回值类型 方法名(参数类型-->使用泛型){
方法体;
}
什么时候确定泛型的数据类型:
调用方法,传递的参数是什么类型,方法的泛型就是什么类型
*/
public class GenericMethod {
//定义含有泛型的方法(重点)
public <M> void method01(M m){
System.out.println(m);
}
//定义含有泛型的静态方法(了解)
public static <S> void method02(S s){
System.out.println(s);
}
//定义含有泛型的方法,返回值类型使用泛型(了解==>看源码)
public <AAA> AAA method03(AAA aaa){
System.out.println(aaa);
return aaa;
}
}
/*
定义含有泛型的接口
*/
public interface GenericInterface<I> {
//定义抽象方法,使用接口上的泛型,作为参数的类型
public abstract void show(I i);
}
/*
含有泛型的接口:第一种使用方式
定义一个类,实现含有泛型的接口,在实现接口的同时,指定接口泛型的数据类型
格式:
public class GenericInterfaceImpl1 implements GenericInterface<String>{
重写接口中的方法,使用指定的类型String
public void show(String s) { }
}
public class GenericInterfaceImpl1 implements GenericInterface<Integer>{
重写接口中的方法,使用指定的类型Integer
public void show(Integer integer) { }
}
*/
public class GenericInterfaceImpl1 implements GenericInterface<Integer>{
@Override
public void show(Integer in) {
System.out.println(in);
}
}
/*
含有泛型的接口:第二种使用方式
定义类实现含有泛型的接口,接口使用什么泛型,实现类就使用什么泛型
实现类跟着接口走,就和定义一个含有泛型的类是一样的
格式:
public class GenericInterfaceImpl2<I> implements GenericInterface<I>{
重写的方法使用接口上的泛型
public void show(I i) { }
}
注意:
创建对象的时候,确定泛型的数据类型;创建对象是什么数据类型,泛型就是什么数据类型
*/
public class GenericInterfaceImpl2<I> implements GenericInterface<I>{
@Override
public void show(I i) {
System.out.println(i);
}
}
/*
泛型的通配符
?:代表可以接收任意的数据类型
?已经由java定义好了,我们可以直接使用
*/
/*
泛型的通配符只能作为方法参数的数据类型使用,不能创建对象作为数据类型使用
*/
//ArrayList<?> list = new ArrayList<>();
//list.add(1);
//list.add("a");
/*
泛型通配符的高级使用
泛型的通配符: ? 代表可以接收任意数据类型的数据
泛型的上限限定: ? extends E==>传递的未知类型?只能使用E的子类或者是E本身
泛型的下限限定: ? super E==>传递的未知类型?只能使用E的父类或者是E本身
*/