JAVA基础知识二(面向对象、常用API)

五、面相对象

1.面向对象

面向过程和面向对象都是解决问题的一种思想模式。

面向过程:指的就是按照一定的步骤,逐一执行,将问题进行解决。

相当于是一个 执行者 角色。

面向对象:指的就是找对象(对象内部应该有所需要的那些功能)解决问题。

相当于是一个 指挥者 角色。

找对象,创建对象,调用其功能(方法)

封装对象 创建对象 调用其功能(方法)

注意:在java中,什么都是对象,具体的,抽象的、有生命的、无生命的都是对象

千万不要局限于指的是人。

比如: 花、草、天气、电脑、人....

面向对象特征:

封装 继承 多态

2.类和对象之间的关系

引用类型: 数组 类 接口 枚举

类: 一种数据类型

使用class来定义的都是该类型对应的数据

一组属性和行为的集合,即一组变量和方法的集合。

属性: 数据,变量

行为: 功能,方法

是用来描述一类事物的,将这类事物的共性内容进行抽取,封装到类中。

比如: 描述人这类事物

属性: 人这类事物的共性数据描述 ,如:身高、体重、姓名...

行为: 人这类事物的共性能做的事情,如:吃饭、睡觉、打游戏...

对象:指的是一类的真实存在的个体(实例)。

形象上理解: 类相当于是模板,对象是一个真实个体

如:类:class Phone{} 对象: new Phone()

定义类格式:

修饰符 class 类名{

属性;... 变量

行为;... 方法,将修饰符static去掉(因为加上static 就是静态方法,静态方法是一种特殊的方法,又称类方法,是在加载类的时候直接进入内存,不需要实例对象就可以调用,类名.方法名 就可以调用)

}

创建对象:

类名 对象名 = new 类名();

访问类中的成员变量或成员方法:

对象名.成员名

3.对象内存的理解

创建一个对象:

Person p = new Person();

对象实例化过程:

1.加载Person.class文件到方法区

2.在栈中创建p引用变量,是Person类型的

3.在堆中开辟空间,并分配地址值

4.在堆中存储默认值

5.将地址值赋值给p变量,p引用/指向了该空间

注意:class只加载一次。

Person p1 = p;

将p的值赋值给p1,说明p和p1指向同一个对象。

4.成员变量和局部变量的区别

\1. 书写位置

成员变量: 类中,方法外

局部变量: 方法中,方法上,语句中

\2. 内存位置

成员变量: 在堆中

局部变量: 在栈中

\3. 作用域

成员变量:整个类中都可以使用

局部变量:在当前定义的所属的大括号中

\4. 默认值

成员变量:有默认值,取决于数据类型

局部变量:没有默认值,需要赋值后才能使用

\5. 生命周期

成员变量:创建对象存在,对象销毁消失。

销毁就是被gc回收。没有引用变量指向的对象就是垃圾,等待被回收。

局部变量:随着方法进栈存在,随着方法出栈消失。

5.匿名对象

1.字面理解:就是没有名字的对象。

2.实际含义:创建的对象,没有引用变量来指向。

例如: new Person();

3.访问属性:

没有意义,访问完称为垃圾,等到被gc回收。

4.访问方法:

有点意义,能调用一次方法,仅仅是一次。

测试某个方法是否逻辑正确,可以创建匿名对象去调用此方法。

5.作为参数传递:

该对象后期不再进行使用,就是用匿名方式传递,对象成为垃圾最终会被回收。

如果使用有名方式传递,该对象不会是垃圾。

6.作为方法的返回值:

如果返回的是匿名对象,如果有变量接接这个结果,该对象不是垃圾。

如果是没有变量来接受,该对象方法执行完就成为垃圾。

6.封装

面向对象的特征,强调的是对象的封装。

与对象有关的是:属性和行为。

概念:将对象的属性或行为隐藏起来,对外提供公共的给访问方式。

关键字:

private:

权限修饰符,私有的意思,被修饰的内容,只能在当前类中使用。

修饰的是类中的成员。

成员:变量、方法、类(内部类)

public:

权限修饰符,权限最大,是公共的意思。

属性私有化:对外提供两个方法,一个是用于给属性进行赋值的,一个是用于给属性获取。

创建的方法的名字是自定义的,主要是合法的标识符就可以的。但是,对于这样的一组方法有一个规范,建议大家都遵守,方法名的格式:

set属性名和get属性名

例如:setName 赋值 getName获取

问题:

成员位置和局部位置变量名重名,导致赋值不成功。

java有一个原则,叫做就近原则,意思就是内部有直接用,不出去找如果没有才出去找。

解决:

this:

是一个隐藏的变量,任何一个类中都有。

代表的是当前类对象的引用,谁调用this所在的方法,那么它就代表谁。

结论:

类中的成员(变量和方法),想要访问,必须通过 对象名.成员名 来访问。

直接调用访问,是因为前边省略了 this.

解决重名问题必须写,其他情况可以省略。

注意:

不是说属性和行为私有了就是封装,私有只是封装的一种体现。

好处:

1.提高代码的安全性。 2.提高代码的维护性

7.构造方法

this:

1.解决成员位置和局部位置变量名重名问题。

2.调用重载的构造方法

名称:构造方法,也叫做构造器,构造函数

普通
​
  修饰符  返回值类型 方法名(参数列表){
​
public  int  getmax (int a ,int b){
​
    return 返回值;
​
    return  a >b ? a: b ;
​
}

构造方法格式:

    //构造方法
    修饰符     方法名(参数列表)
    public  Persons(){
         super();
        System.out.println("我执行了~~~");
    }
​
    public  Persons(int age){ 
        this();
        this.age = age;
    }
​
    public  Persons(String name , int age){ //name = zhangsan  age = 20
       this(age);  //调用重载的构造方法
        this.name = name;
        this.age = 40;
    }

修饰符: public private 默认

方法名: 类名,包括大小写一致

特点:

1.创建对象时,根据new后边的实参列表,找到对应的构造方法去调用执行

2.支持方法重载

3.构造方法中没有 return 返回值; 语句,想要有return关键字,只能是 return;

作用:

主要是用于给对象的属性进行初始化。

说明:注意构造方法中不一定非要是属性的赋值语句,也可以有循环、调用方法等。

构造方法也是方法,只不过比较特殊而已,因此也是可以对应的逻辑代码语句的。

对象只能创建一次,创建的时候会自动调用构造方法来完成属性的赋值操作,构造方法对于该对象来说,只能调用一次。

问题1:

既然构造方法可以给属性进行赋值,还需要set方法?

依然需要,因为构造方法仅仅是对象创建是执行,set方法是在对象创建后可以多次调用执行,对属性值进行改变。

问题2:

构造方法能调用其他普通方法?

是可以的,但是这种调用比较少。

问题3:

普通方法能调用构造方法吗?

不能,构造方法只能在创建对象的时候完成初始化。

问题4:

Person p = new Person(“张三”,30);

对象的实例化过程:

1.加载Person.class文件到方法区

2.在栈中创建p引用变量,是Person类型的

3.在堆中开辟空间,并分配地址值

4.在堆中存储默认值

5.属性如果有显示值,那么进行显示初始化,如果没有跳过此步

6.执行构造方法初始化,将张三和30赋值给对象的属性

7.将地址值赋值给p变量,p引用/指向了该空间

问题5:

重载构造方法的调用。

    //构造方法
    public  Persons(){
        // this("",18);         至少有一个不能写this,是给super留位置,就算是不写super,默认第一行也是有的
        System.out.println("我执行了~~~");
    }
​
    public  Persons(int age){ 
        this();
        this.age = age;
    }
​
    public  Persons(String name , int age){ //name = zhangsan  age = 20
       this(age);  //调用重载的构造方法
        this.name = name;
        this.age = 40;
    }

需要使用 this(实参); 这个语句来实现。

要求:这个语句必须放在构造方法的第一行。目的就是为了让该语句优先执行。

注意:重载形式的构造方法的第一行,至少有一个构造方法不能写 this(实参); 语句,不然就是死循环。

问题6:

之前创建对象时,类中没有定义过构造方法,对象也创建成功了?

类中没定义是因为系统提供了一个无参数,无方法体的构造方法 public 类名(){}。

但是,在类中定义过了构造方法了,那么系统不再提供,必须以编写的构造方法的格式来创建对象。

8.JavaBean类

指的就是一个实体类(对象类),是一种规范。

类中成员:

1.属性必须私有化

2.必须有set和get方法

3.必须有无参数构造方法,显示

4.有参构造(可选)

5.用于返回属性信息方法(可选)

类要求:必须是public修饰的类。

package com.ujiuye.day08;
​
//描述某个事物类
//该类要符合JavaBean的规范
public class Students {
    //1.属性私有化
    private  String name;
    private  int age;
​
    //2.无参数构造方法
    public  Students(){}
​
    //4.有参构造方法 可选
    public  Students(String name,int age){
        this.name = name;
        this.age = age;
    }
​
    //3.set和get方法
    public void setName(String name) {
        this.name = name;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public String getName() {
        return name;
    }
​
    public int getAge() {
        return age;
    }
​
    //5.返回属性信息的方法  可选
    public  String  getInfo(){
        return  name +"...."+age;
    }
}

9.继承

static关键字

静态的意思,是一个成员修饰符。可以修饰类中的成员变量、成员方法、成员内部类。静态过的变量和方法在创建对象之前就已经在内存中,直接进栈,不需要对象

没有静态前:描述一个类型后,创建该类型对象,发现每个对象中都有一个共同的数据,这样导致内存空间浪费,如果要对该值进行修改,需要修改多次,维护成本增高。

说明:这样做也是可以的,不做优化没问题。

静态后:在内存中,只是开辟一块空间,存储共同数据,这个数据可以被该类型的所有对象所共享,如果值要改变,仅仅修改一次即可。降低内存空间浪费和维护的成本。

静态变量的方法: 在变量前面加上 static 修饰符即可

static修饰成员变量特点:

1.在类加载时,静态变量存储在方法区的静态区域,并存储默认值。

2.被该类型的所有对象所共享

3.优先于对象存储在内存中

4.生命周期长,随着类的加载而加载,随着类的消失而消失

5.被static修饰的变量

静态变量 、类变量 ,与对象无关

访问方式 : 类名.静态变量名 推荐

对象名.静态变量名

注意:千万不能为了调用简单而使用static就是变量,当所有对象共享同一个资源数据时,使用static修饰。

成员变量和静态变量区别:

\1. 内存位置

成员变量:存储在堆中

静态变量:存储在方法区中的静态区域

\2. 访问方式

成员变量: 对象名.成员名

静态变量: 对象名.成员名 类名.成员名 推荐

\3. 生命周期

成员变量:随着对象创建而存在,随着对象被gc回收而消失

静态变量:随着类的加载而加载,随着类的消失而消失

\4. 称呼上:

成员变量: 对象变量 实例变量

静态变量: 类变量

访问局限:

1.静态方法中可以访问静态成员(变量和方法)

2.静态方法中不能访问非静态成员

3.非静态方法中既可以访问非静态也可以访问静态

总结:静态方法中不能出现与对象直接有关的内容,因为静态方法在加载类的时候就已经进入内存,静态方法不需要实例对象就可以直接调用,通过 类名.静态方法名。

在静态方法中不能出现this和super关键字:因为this和super关键字在实例中只能通过对象来调用,静态方法不出现与对象有关的内容,所以不能出现this和super关键字。

工具类:

类中没有所需要维护的数据时,仅仅只有方法。

步骤:

1.定义类,类名通常是见名知意

2.私有化构造方法:因为别人写好的功能,不希望有人改动。

3.方法都是静态的,方便直 接类名.方法名 拿来使用,不用创建实例对象。

继承

模拟现实生活中的父和子的关系,在java中也有类似的关系,指的就是类和类间也有继承关系。当描述Student 和 Teacher两个不同的事物时,发现有共性的内容(属性和行为),将这些内容进行提取,定义到Person类中,让Student和Teacher与Person产生关系,Student和Teacher可以直接使用Person类中的内容,这种关系就是---继承。

定义:

从一个类中派生出(衍生出)其他类的过程。

原来的类称为: 父类、超类、基类

派生出的类称为: 子类

关键字:

extends 继承

class A extends B{}

好处:

1.提高了代码的复用性

2.面向对象的第三特征--多态

弊端:

增强了耦合度。

子类继承父类后,相当于将父类中的成员继承,可以直接使用。

子类只需要定义自己特有的成员属性和成员方法即可,也可以不定义。

注意:

1.构造方法不继承 因为构造方法名要求与类名一致,如果继承则冲突。

2.私有成员不被继承 (官方文档显示)

实际在子类中依然有父类中的私有成员,只不过是子类不能直接对其进行操作,只能通过继承的get和set方法间接使用。

在java中,一个类只能有一个父类,这是java的单继承特点。

一个父类可以有多个子类。这些子类是平级关系,即兄弟关系。

注意:

不能为了提高代码的复用性而乱使用继承,必须是有 is--->a关系,就是一种类似于父子间继承的关系。

继承中成员变量的特点:

1.现在子类局部范围找

2.子类成员方法范围找

3.父类的成员方法找

4.父类的父类找....... 知道找到object ,如果都找不到就会编译报错

this:

代表的是当前类对象的引用,可以访问子类中成员也可以访问父类中成员,就近原则,子类中有就用子类的,子类没有就用父类的

super:

它的用法和this基本上是一致的,都可以访问成员变量和成员方法,只不过super访问的是父类中的成员,因为super代表的是父类型引用。不管子类有没有都是只用父类的。

问题:创建子类对象时,父类对象创建了吗?

没有创建。只不过是子类中持有一个父类型引用,即super,可以去访问父类中的成员。

方法重写

子类和父类中,有相同的方法定义,方法名相同,方法的主体不同,创建子类对象调用该方法,运行的是子类中的内容,这种现象叫做方法的重写/覆盖。

overload:重载

同一个类中,方法名相同,参数列表不同,与返回值类型无关

overried:重写

在子父类中,子类重写父类中的方法

为什么要重写?

继承的方法的方法主体不满足于子类的需求。

重写方法要求:

1.私有方法不重写。即使在子类中写了该方法,貌似重写,实际是重新定义。

通过@Override注解来验证,这个注解写在重写方法的上边。

2.重写方法的权限修饰符要大于等于父类方法的

权限修饰符 public > protect > default (默认) > private

3.重写方法的返回值类型小于等于父类方法的返回值类型

为了保证重写正确:

修饰符 返回值类型 方法名 参数列表 都与父类的一致。

继承中的构造方法

创建子类对象时,发现父类的构造方法也执行了(无参数的),是因为子类构造方法的第一行有一条隐藏的 super();语句,这条语句的作用就是调用父类的无参数构造方法。

构造方法: 用于给属性进行初始化。

为什么要执行父类构造方法?目的就是为了让父类的属性先进行初始化。在子类属性执行初始化之前,父类属性先初始化子类所有的构造方法调用之前都会调用父类的无参构造方法每一个子类构造方法之前都会有一个super();

注意:父类的构造方法一定要执行,而且一定是在子类构造方法之前执行的。 父类中没有无参数构造方法,子类构造方法的第一行必须显示写出super(参数)语句。this() 和 super()都需要放在构造方法的第一行,因此它俩不能同时存在。

//第一种:
  public SubClass(){ // 自动调用父类的无参数构造器
    System.out.println("SubClass");
  }  
  
  public SubClass(int n){ 
    super(300);  // 调用父类中带有参数的构造器
    System.out.println("SubClass(int n):"+n);
    this.n = n;
  }
//第二种
  public SubClass2(){
    super(300);  // 调用父类中带有参数的构造器
    System.out.println("SubClass2");
  }  
  
  public SubClass2(int n){ // 自动调用父类的无参数构造器
    System.out.println("SubClass2(int n):"+n);
    this.n = n;
  }

10.知识总结

\1. 面向过程:当需要实现一个功能的时候,每一个过程中的详细步骤和细节都要亲力亲为。

\2. 面向对象:当需要实现一个功能的时候,不关心详细的步骤细节,而是找人帮我做事儿。把需求不自己亲自解决,而是交给对象解决。对象是我们提前设计好的能有一定功能的代码,当我们需要的时候直接调用对象实现其功能。

比如:洗衣服的面向过程的理解就是,每次洗衣服都拿盆放水放洗衣液自己

洗完拧干晾衣服,每次洗衣服都是这个重复的工作。面向对象的思想就是,我把这些重复的工作设计到一个全自动洗衣机里,

或者买一个全自动洗衣机,我每次洗衣服的时候只需要把衣服放进洗衣机打开开关就行。自己设计洗衣机就是自己设计代

码块,买洗衣机就是拿别人设计好的-可以实现该功能的代码,我们直接复制过来。

\3. 类和对象的关系:

a) 类是抽象的,通常不能直接使用。好像是一张手机设计图纸,存放了手机的大小形状颜色功能价格和设计了打电话发短信的方法。

b) 对象是具体的,根据类创建一个对象使用,也就是根据图纸创造一个手机,这个手机有具体的信息,颜色价格功能等。

\4. 如何定义一个类:成员变量、成员方法。

a) 成员变量:直接定义在类当中,在方法外面。

b) 成员方法:去掉static关键字,其他和此前的普通方法一样。(目前最基础阶段这么理解)

\5. 如何根据类创建对象,格式:类名称 对象名 = new 类名称();

\6. 如何使用对象:

a) 使用成员变量:对象名.成员变量名

b) 调用成员方法:对象名.成员方法名(参数)

\7. 局部变量和成员变量的不同:

a) 定义的位置不同

b) 内存的位置不同

c) 生命周期不同

d) 默认值不同

e) 作用域不同

\8. private关键字用法:直接写在成员变量前面,类外面不能直接访问,确保安全性。间接访问:编写一对儿Getter Setter方法。(特例:如果是boolean类型,getXxx必须叫做isXxx的形式。

\9. this关键字典型用法:用来区分同名的成员变量和局部变量。在成员变量的前面写上“this.”前缀即可。

\10. 构造方法:专门用来创建对象的方法,通过new关键字创建对象就是在调用构造。

a) 构造方法不能写返回值类型,连void都不能写。

b) 构造方法的名称必须和所在的类名称完全一样,大小写也要一样。

c) 构造方法也是可以重载的。

d) 构造方法如果没有定义,默认送一个;如果定义了,那么默认的不再赠送。

\11. 如何定义一个标准的POJO类

a) 所有的成员变量都用private修饰

b) 为每一个成员变量编写一对儿Getter Setter方法

c) 编写一个无参数的构造方法

d) 编写一个全参数的构造方法

11.代码块

使用大括号包围起来的代码区域,里边可以是多条代码

1.局部代码块

书写位置: 方法中

作用:控制局部变量的作用域

在局部块中,可以使用它所在局部位置中所定义过的变量,出了局部块,不能使用块中

定义的变量。在一个局部中,可以定义多个局部块。例如:在一方法中的代码块,只可以使用这个方法内定义过的变量,不可以使用这个方法外的常量,而且这个代码块内的定义过的变量只在这个代码块内有效。

2.构造代码块

书写位置:类中方法外

作用:用于给对象进行初始化的,优先于构造方法执行

在构造块中,编写的是所有对象共性的内容提取。在一个类中,可以出现多次的构造块,

按照从上到下的顺序,依次执行构造块,然后在执行对应的构造方法。

对象的构造方法执行过程

1.先执行super()语句,意味着父类必须先执行

2.执行构造块,前提是有

3.执行构造方法的其他代码

4.调用几次构造方法就执行几次静态块

public class Demo1 {
    //构造块
    {
        System.out.println("code1执行了");     //构造快1
    }
    public  Demo1(){
        super();
        System.out.println("demo2 执行了");
    }
​
    public  Demo1(int x){
        System.out.println("demo2 执行了--"+x);
    }
​
    public static void main(String[] args) {
        new  Demo1();                           //在调用无参构造的时候
        new  Demo1(10);
    }
​
    {
        System.out.println("code2执行了");     //构造块2
    }
}

3.静态代码块

书写位置:类中方法外,使用关键字static修饰

static{

....

}

类加载时执行,由于类仅仅加载1次,静态块只执行一次。

作用:静态变量初始化

类加载时,就需要完成一些动作,只需要执行一次的,比如:加载驱动。

在一个类中,静态块也可以出现多次,按照从上到下的顺序依次执行。

注意:静态块是在类加载完成前的最后一步去执行的。

public class Demo1 {
    static  int num ;
    //静态块
    static{
        num = 100;
        System.out.println("static code1111 执行了");
    }
​
    public static void main(String[] args) {
        
    }
​
    static{
        num = 100;
        System.out.println("static code1222 执行了");
    }
}

构造块和静态块综合练习

public class Demo1 {
​
    {
        System.out.println("A");
    }
    static{
        System.out.println("B");        
    }
​
    public static void main(String[] args) {
        new Demo1();
        new Demo1();
    }
    public Demo1(){
        System.out.println("E");
    }
​
    {
        System.out.println("C");
    }
​
    static{
        System.out.println("D");
    }
}
//      运行结果 bdace  ace
// 因为运行的时候类先加载,只要加载类就要运行静态代码块,但是只加载一次,运行构造方法之前需要运行构造块,构造方法调用几次构造块就执行几次,多个构造块的话按照从上到下的顺序。

4.同步代码块(多线程)

12.抽象类

1抽象类的特点

也是类,只不过是一个特殊一点的类。

1抽象类和抽象方法必须用abstract修饰

2抽象类中不一定有抽象方法,有抽象方法的一定是抽象类

3抽象类不能被实例化

4抽象类必须有子类,抽象类的子类要么重写这个抽象类的所有方法,要么这个子类也是一个抽象类。

abstract:

抽象的意思,是一个修饰符,可以修饰类和方法。

修饰的类:叫做抽象类

修饰的方法:叫做抽象方法。

abstract不能和private、static、final共存。

2成员:

抽象方法、成员变量、成员方法、构造方法

3.成员特点

成员变量:

可以是变量、也可以是常量

构造方法:

有构造方法,但是不能被实例化,用于子类访问父类数据的初始化

成员方法

可以有抽象方法,用于限制子类完成某些动作

也有非抽象方法,提高代码的复用性

4.抽象类的应用条件

1.该类不允许创建对象,必须有子类

2.进行多个子类内容抽取时,发现部分方法子类都将其进行了重写,父类中这些方法没必要带有方法体,因此将这些方法定义为抽象方法,抽象方法要在抽象类中。

一旦将类定义类抽象类,有一个强迫性的行为,强迫继承它的非抽象子类必须重写抽相方法。

5.final关键字

最终的、最后都意思,是一个修饰符。

修饰:类、方法、变量。

修饰类:

final class ,最终类,不能被继承。

修饰方法:

final method , 最终方法,不能被重写。

多个修饰符进行修饰时,修饰符是没有顺序的,谁在前谁在后都行。

修饰变量:

final 即可修饰成员可以修饰局部变量,修饰后叫做最终变量,不能改变。

被final修饰的变量就可以叫做常量。

常量:字面值常量 123 “hello”

符号常量

常量名: 全部大写,多个单词间使用_分隔

例如: public/private static final double MY_PI = 3.14;

final可以修饰基本类型变量 也可以修饰引用类型变量

如果修饰引用类型变量,地址值不能改,引用变量所指向的容器中的数据可以改变

  • final数据只可以被引用,不能被修改,且必须给出初始值。其优点如下

    (1)增加程序的可读性,从常量名可知常量的含义 (2)增加程序的可维护性,只要在常量声明的处修改常量的值,就可以自动修改程序中所有地方使用的常量值

  • final方法的好处

    (1)保持父类中某些方法的行为在继承中不发生改变 (2)提高运行效率。声明为final的方法,Java采用内联(inline)调用,即将方法代码直接插入到调用位置,这样可以降低方法调用的额外开销(入栈、跳转、执行、返回和清除栈等操作的时间和空间开销)

  • static()和private()是隐式的final()方法

13.多态

字面理解:多种状态。比如,波斯猫既是猫类,有事动物类,有时候需要调用动物类的吃饭方法,有时候需要调用猫类的抓老鼠方法,所以波斯猫有时候是猫类,有时候是动物类。

引申含义: 一个对象可以有不同的状态表示。

状态指的就是该对象的引用变量类型。

多态前提: 1.有继承和实现关系 2.有父类引用指向子类对象

多态中访问的特点: 1.成员变量: 编译执行都看左边 2.成员方法:编译看左边,执行看右边

多态表现:父类型引用指向子类的对象

多态的好处和弊端: 好处:提高了程序的扩展性,具体的表现:使用父类作为参数,将来使用的时候,使用具体的子类参与操作。 弊端:不能使用子类特有的功能。

站在对象的角度:可以使用本类型或父类型的引用变量来指向

站在引用变量类型角度: 该引用变量可以指向不同的子类对象。

多态中的转型 向上转型: 从子到父 ,父类引用指向子类对象 Animal a = new Cat(); 向下转型: 从父到子 ,父类引用强转子类对象 Cat c = (Cat) a ; f是一个定义过的父类引用

a能强转为 cat 是因为a 本来就是一只猫 假如Animal a = new Dog() 后, Cat c = (Cat) a 就会显示类型转换失败,因为a现在指向一只狗。

instanceof :比较运算符,结果是boolean类型。 格式:变量名 instanceof 类名

左边的引用变量所指向的对象是否是右边的类型

public class Animal{    //定义一个动物类
    void eat(){     //定义一个方法吃东西
        System.out.println("吃东西")
    }
}
​
public class Cat extends Animal{    //定义一个猫类
    void eat(){     //重写吃这个方法
        System.out.println("吃鱼")
    }
}
​
Cat boscat = new Cat;
在猫类中产生一个具体的对象波斯猫,由于猫类是动物的子类,这个波斯猫有时候是需要是动物的角色,有时候需要时猫的角色。
    这个猫在不同时候有不同的状态,这就是多态。

instanceof :比较运算符,结果是boolean类型。 格式:变量名 instanceof 类名 左边的引用变量所指向的对象是否是右边的类型

public static void main(String[] args) {
        Animal animal =new Cat();
        printEat(new Dog());
        printEat(animal);
    }
    public static void printEat(Animal animal){ //括号里边是父类型的参数
        if (animal instanceof Cat){     //判断条件(父类型参数 instanceof 子类) 返回值是布尔类型
            Cat cat = (Cat)animal;
            cat.eat();
            cat.mouse();
        }else if (animal instanceof Dog){
            Dog dog = (Dog)animal;
            dog.eat();
            dog.kanmen();
        }else{
            animal.eat();
   }
}

多态的参数

//定义一个动物类
public class Animal {
    void eat(){
        System.out.println("吃");
    }
}
​
//定义一个猫类,并将eat方法重写
public class Cat extends Animal {
    @Override
    void eat() {
        System.out.println("吃鱼");
    }
    void mouse(){
        System.out.println("抓老鼠");
    }
}
​
//创建一个测试
public class test {
    public static void main(String[] args) {
        Animal animal =new Cat();
        printEat(new Dog());
        printEat(animal);
    }
    //定义一个吃的方法,使用父类作为参数,将方法体强转,这个代码就适应于多种情况
    public static void printEat(Animal animal){     
        if (animal instanceof Cat){
            Cat cat = (Cat)animal;
            cat.eat();
            cat.mouse();
        }else if (animal instanceof Dog){
            Dog dog = (Dog)animal;
            dog.eat();
            dog.kanmen();
        }else{
            animal.eat();
        }
    }
}

14.接口

理解: 不同事物间的共性行为的抽取。

引申含义:定义一个接口,就是在定义一个规则,这些规则指的是方法的定义。

不同事物进行抽取时,只能抽取方法的定义,不能抽取方法的主体,因此抽取的内容符合抽象方法的定义,因此接口中内容是抽象方法。方法的参数列表、方法名、返回值一旦确定,使用时必须按照定义的这些内容去使用,这些方法叫做规则。

格式:

修饰符 interface 接口名{

常量;

抽象方法;

}

接口中成员的修饰符是固定的,都是公共成员。

常量: public static final

方法: public abstract

定义接口时如果修饰符没有写全,编译没问题,编译器会自动将缺失的修饰符补全。

特点:

1.不能实例化

2.需要有实现类,实现类需将接口中的方法全部实现,子类才能创建对象。

class 子类名 implements 接口名{}

3.支持多态 父接口类型的引用指向自己的实现类对象

4.接口中是没有构造方法的

类、接口间的关系:

类和类间关系:单继承

类和接口关系:多实现,接口名间使用逗号分隔即可

接口和接口关系:多继承

实际开发中:
 class  A   extends  B  implements C,D{}  多见
​
 class B  implements C,D{}
 class A  extends B{}

接口和抽象类的区别

参数抽象类接口
默认的实现方法可以有默认的方法实现完全是抽象的,根本不存在方法实现
实现子类使用extends关键字来继承抽象类,如果子类不是抽象类的话,就需要重写抽象类中的所有方法实现类使用implement关键字来实现接口,需要重写接口中的所有方法
构造器可以有构造器不能有构造器
与正常JAVA类的区别除了不能实例化对象以外,和一个普通的类没有区别是完全不同的构造类型,接口不属于类
访问修饰符可以有public,protected,default修饰符接口的默认修饰符是public ,不能使用其他的修饰符
main方法可以有main方法-,并且我们可以运行它没有main方法,因此不能运行
多继承抽相方法可以继承一个类和实现多个接口接口可以继承一个或多个替他接口
速度比接口快速度稍微有点慢,需要时间去寻找类中的实现方法
添加新方法如果需要添加新的方法,可以提供默认的实现,不需要改变现在的代码如果在接口中添加方法,必须改变实现该接口的类

抽象类是对对象属性和行为的抽象,通常用来抽象属性。

接口只是对对象的行为的抽象,不能用来抽象属性。

什么时候使用抽象类和接口

如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。

如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。

如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。

15.内部类

1.概念

概念:将一个类定义到另一个类的里边,将里边的类叫做内部类或内置类。

描述两类事物时,发现这两个事物间应该有包含关系,这时可以使用内部类。

比如:教学类和教室 身体和心脏

2.分类

按照位置:成员内部类和局部内部类

按照有无类名: 有名内部类和匿名内部类

3.各类区别

成员内部类:

将类定义到另一个类的里边,位置即是类中方法外,可以使用成员修饰进行修饰。

默认、private、static

默认内部类:

类中成员: 非静态成员 和 静态常量

可以访问它所属的外部类中的成员

访问内部类中的成员,需创建内部类对象,方式有两种:

1.直接方式: 外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

2.间接方式:

在外部类中定义方法,在该方法中创建内部类对象,调用内部类中成员。

在外部其他类中创建外部类对象,调用定义的方法。

私有内部类:

内部类前边使用private关键字修饰了,具体了私有特性,意味着只能在当前类使用。

类中成员: 非静态成员 和 静态常量

可以访问它所属的外部类中的成员

访问内部类中的成员,需创建内部类对象,方式只有1种:

间接方式:

在外部类中定义方法,在该方法中创建内部类对象,调用内部类中成员。

在外部其他类中创建外部类对象,调用定义的方法。

静态内部类:

内部类前边使用static关键字进行修饰了,因此具备静态特性。 别名:嵌套类。

类中成员:静态和非静态都可以定义

类中的静态方法只能访问内部类中的静态成员;类中的非静态方法能访问内部类中的静态成员也可以访问非静态。

由于类是静态的,只能访问它所属的外部类中的静态成员。

访问类中成员:

静态成员:

直接方式: 外部类名.内部类名.方法名

间接方式: 在外部类中定义方法,在方法中 内部类名.方法名

在外部其他类中创建外部类对象,调用该方法

非静态成员:

直接方式:new 外部类名.内部类名().方法名

间接方式:在外部类中定义方法,在方法中 new 内部类().方法名

在外部其他类中创建外部类对象,调用该方法

局部内部类:

将类定义到局部位置中,即方法中。

注意:该内部类不能使用成员修饰符修饰。

类中成员: 非静态 和 静态常量

可以直接访问它所属的外部类中的成员。

访问内部类中成员,需创建内部类对象,在它所在的局部位置中去创建。

注意:局部内部类访问它所在局部位置上的变量时,不能对该变量值进行修改,因为该

变量前边有final,jdk8以上不需要手动写final,编译器会自动补上。

匿名内部类

前提:存在一个类或者一个接口,这个类可以是具体的也可以是抽象的

格式: new 类名或者接口名(){

方法重写;

};

本质:一个继承了该类或者实现了该接口的匿名对象

建议:

\1. 子类中不要写自己特有方法

\2. 父类中或父接口中 都不要有太多需要重写的方法 不超过3个

//定义一个接口
public interface Inter {
    void show();
}
​
//创建外部类和内部类,匿名实现一个接口
public class Outer4{
    public void method(){
        new Inter(){
            @Override
            public void show(){
                System.out.println("匿名内部类");
            }
        }.show;
    }
}
​
//也可以这样
public class Outer4{
    public void method(){
       Inter i = Inter new Inter(){
            @Override
            public void show(){
                System.out.println("匿名内部类");
            }
        };
        i.show;
    }
}
​
//创建实例调用匿名内部类中的方法;
public class Outdemo{
    public static void main(String[] args){
        Outer4 o = new Outer4();
        o.method();
    }
}
​
​

成员内部类 默认内部类(前面不加修饰)成员内部类 私有内部类(前面private修饰)成员内部类 静态内部类(前面static修饰)
类中成员静态和非静态静态和非静态静态和非静态
访问内部类中成员直接:外部类名.内部类名 对象名 = new 外部类名().new 内部类名(); 间接:在外部类中定义方法,在该方法中创建内部类对象,调用内部类中成员。在外部其他类中创建外部类对象,调用定义的方法。间接:在外部类中定义方法,在该方法中创建内部类对象,调用内部类中成员。在外部其他类中创建外部类对象,调用定义的方法静态成员: 直接方式: 外部类名.内部类名.方法名 间接方式: 在外部类中定义方法,在方法中 内部类名.方法名在外部其他类中创建外部类对象,调用该方法 非静态成员: 直接:new 外部类名.内部类名().方法名 间接:在外部类中定义方法,在方法中 new 内部类().方法名
内部类中的方法访问其他可以访问外部类和内部类中的所有的成员可以访问外部类和内部类中的所有的成员内部类中的静态方法可以访问外部类和内部类中的静态成员 内部类中的静态方法可以访问外部类和内部类的静态和非静态成员
局部内部类
类中成员静态和非静态
访问内部类中成员可以访问外部类和内部类中的所有的成员
内部类中的方法访问其他访问内部类中成员,需创建内部类对象,在它所在的局部位置中去创建。
注意:局部内部类访问它所在局部位置上的变量时,不能对该变量值进行修改,因为该变量前边有final,jdk8以上不需要手动写final,编译器会自动补上。

package和import关键字

package:

包的意思,创建一个包,相当于是电脑磁盘中的一个文件夹。

作用:

1.分类管理类文件

2.在不同包中可以出现同名类

3.可以将源文件和类文件进行相分离

告诉jvm当前类应该存储在那个地方。

语法:

package 包名;

规范: 小写单词或字母组成

公司域名倒置.项目名.模块名[.子模块]*;

例子: com.ujiuye.cms.login;

注意:该语句在一个源文件中只能出现一次

一定是在有效代码的最上边。

带包编译:

javac -d 目录 源文件名.java 自动创建包中的文件夹

注意:类中有package语句,那么类名有了限定,完整形式为:包名.类名

带包执行:

java 包名.类名

jvm启动执行时,默认导入的是java.lang包下的所有类,因此该包下的所有类直接使用,不需要import关键来进行导入。

import:

导入的意思。

告诉jvm,当前类中要使用的其他类去哪找。

语法格式:

import 包名.类名; 找指定的类

import 包名.*; 找指定包中的所有类

该语句位置是在package和class中间,可以出现多次。

jdk5.0特性:

静态导入:导入静态成员。

import static 包名.类名.静态成员名;

import static 包名.类名.*;

好处:简化代码书写,省略了:类名.

弊端:降低了代码的阅读性,不建议过多使用

模板设计模式

设计模式:

是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

一共有23种设计模式。

根据目的划分: 结构型、行为型、创建型。

http://c.biancheng.net/design_pattern/

模板设计模式:

行为型模式中的一种。

将一个抽象类看成是一个模板,此时不能确定实现的逻辑使用抽象方法来表示,此时能明确逻辑实现的就使用具体方法,最终不能明确的由子类来实现,不同子类可以有不同实现方式。

总结:抽象类用来确定一个结构,不能确定部分有子类来实现。

六、API

1.object类

jvm启动,默认导入的是java.lang包中的内容,该包下的内容不需要import进行导入。

概述:

该类是java体系中的根类,所有对象都将该类作为直接或者间接父类

所有对象包括数组都继承了该类中的方法。

构造方法:

Object() :该方法中没有super()语句了。

方法:

boolean equals(Object obj) : 比较两个对象的地址值是否相同

该方法比较的是地址值,没有实际意义,通常会将该方法进行重写,比较有意义数据,通常是类中属性的比较。

== 和 equals区别:

==:

可以比较基本类型也可以比较引用类型

比较基本类型: 比较是数值是否相同

比较引用类型: 比较是的地址值

equals:

只能进行引用类型的比较,比较是地址值 通常会重写,比较属性

int hashCode() :返回对象的哈希码值

每创建一个对象,该对象都会有一个哈希值存在,默认不同对象(object类中的equals)哈希值不同,但是可以通过重写hashCode方法,让不同对象有相同的哈希值。因此该方法是不能判断是否是同一对象的。如果是同一对象的,哈希值一定相同。

String toString() :返回对象的字符串表示。

当打印对象名时,显示调用该方法和不调用打印的结果是相同的,因此打印对象名时这个方法是被自动调用的。

格式: 包名.类名 + @ + 哈希值

这种格式看不懂,建议重写该方法,显示易于看懂的信息,即属性信息。

Class getClass() :用于返回当前jvm正在运行时的类

注意:返回值类型是Class类型,Class是一个类类型。

JavaBean:

1.私有属性 2.无参构造 3.set和get方法

可选: 有参构造 重写toString

2.String类

概述:

1.该类是一个final类,不能有子类。

2.只要出现双引号表示的字面值数据,都是该类的一个实例对象,如“abc”

说明创建字符串对象,可以不使用关键字new。

  1. 字符串是常量,创建后不能改变,能改变的是引用的指向

  2. 由于字符串不能改变,因此被共享。

  3. 字符串底层原理就是字符数组

构造方法:

使用new关键字创建对象时,调用的方法。

单元测试:JUnit

定义方法: public void 方法名(){ ....}

需要在方法的上边加入 @Test 注解,需要导入对应的列库。

注意:项目中不要出现以Test为类名的类。

返回值方法作用
StringString()初始化一个新的String对象,使其成为一个空的字符序列
StringString(byte[] byte)使用平台默认的字符解码器指定的byte数组,构造一个新的String
StringString(byte[] byte,int 开始,int 个数)使用平台默认的字符解码器指定的byte数组,构造一个新的String,指定开始索引和个数
StringString(char[] value)字符数组转化为字符串
StringString(char[] value,int 开始,int 个数)字符数组转化为字符串,指定开始索引和个数
StringString(String orginal)创建一个新的字符串,是原来字符串的副本
判断
booleancontains(字符序列“hello”)当这个字符串包含这个字符序列的时候返回true
booleanendswith(字符或者字符序列)判断字符串是否以指定的内容结尾
booleanstarwith(字符或者字符序列)判断字符串是否以指定的内容开始
booleanequals()判断此字符串与一个字符串是否相等
booleanequalsIgnoreCase()判断此字符串与一个字符串是否相等,不考虑大小写
booleanisEpty()当length()为0 时返回true
获取
charcharat(index)返回指定索引处的char值
intindexof(int ch)返回指定字符在字符串中第一次出现的索引
intindexof(int ch, int fromindex)返回指定字符在字符串中第一次出现的索引,从指定位置开始
StringsubString(star,end)按照索引截取指定字符串
String[]split("d")按照给定的字符串截取,返回一个字符串数组

3.字符串缓冲区对象

String 类型的数据存放在常量池,当创建一个对象时,如果常量池有的话就直接引用,如果没有的话就创建一个。每次对字符串操作就会开辟一个空间储存,比较浪费资源。

缓冲区:

看成一个容器,这个容器的大小可以改变。

字符串缓冲区:

操作过程中可以操作任意类型的数据,操作结束后,得到一个唯一的字符串。

在操作的过程中,一直操作同一个缓冲区。

对象:

StringBuffer和StringBuilder

二者的功能是相同的,

区别是:StringBuffer jdk1.0版本的,多线程安全,效率慢

StringBuilder jdk5.0版本的,多线程不安全,效率快

特点:都是final类,即不能有子类,可变的字符序列。

对象是围绕着 :增删改查进行功能设计的。

构造方法:

new StringBuilder() 常用

new StringBuilder(指定容量)

new StringBuilder(String str) 常用,将字符串转为字符串缓冲区对象

        //创建默认字符串缓冲区,默认长度为16
        StringBuffer s = new StringBuffer();
        System.out.println(s.capacity());
        //创建自带内容的字符串缓冲区,长度为默认+内容长度
        StringBuffer s1 = new StringBuffer("ABC");
        System.out.println(s1.capacity());//16+3
        System.out.println(s1);
        //创建指定容量的字符串缓冲区
        StringBuffer s2 = new StringBuffer(20);
        System.out.println(s2.capacity());

字符串和缓冲区对象之间的转换问题

String---->StringBuilder : new StringBuilder(String str)

StringBuilder ---->String: new String(StringBuilder s)

new StringBuilder().toString()

互转的目的就是为了使用对方的功能或对方的特点。

方法:

增:

append(data) : 将data追加到原有数据的末尾

insert(index,data) :将data插入到index位置上

        //增
        s.append(123).append(1.23).append("sd").append(true);   //1231.23sdtrue
        s.insert(0,"w");    //w231.23sdtrue
        System.out.println(s);

删:

delete(start ,end) :删除[start,end)区间内的字符

deleteCharAt(index):删除index位置上的字符

        //删
        s.delete(0,5);      //删除字符串中的索引为0-4的元素
        System.out.println(s);
        s.deleteCharAt(0);      //删除索引为0的元素
        System.out.println(s);

改:

replace(start,end ,newStr):将[start,end)区间内的替换为newStr

reverse(): 反转

setCharAt(index, newChar) :将index位置上的字符修改为newChar

        s.replace(0,2,"56");        //把字符串中的索引为0-1 的元素替换为56
        System.out.println(s);
        s.reverse();                //翻转所有的元素
        System.out.println(s);
        s.setCharAt(0,'s');         //把索引为0的元素替换为s
        System.out.println(s);

查:

length(): 获取字符长度

capcity(): 获取实际容量

toString():返回字符序列

        //查
        System.out.println(s.length());     //查看字符串的长度
        System.out.println(s.capacity());   //查看字符串的容量
        System.out.println(s.toString());   //查看具体内容,结果是String 类型
        System.out.println(s);              //查看具体内容,结果是StringBuffer 类型

StringBuilder和String作为方法参数时:

    public static void main(String[] args) {
        String s = "abc";       // s指向abc
        test(s);
        System.out.println(s);  //s的指向没有变,结果还是abc
    }
    public static void test(String str ){   //str = s 
        str = "123";
    }
    public static void main(String[] args) {
        StringBuffer s1 = new StringBuffer("123");
        test1(s1);
        System.out.println(s1);
    }
​
    public static void test1(StringBuffer str){
        str.append("abc");          //结果为:123abc    在原来的基础上添加
        str = new StringBuffer("456");      //  new了一个新的容器,和之前没有关系
    }

包装类

java.lang包中的对象。

围绕着基本类型进行设计的,一共有8个对象。

因为基本类型仅仅是表示一个简单的数据,需要能像对象一样,进行方法和属性的访问操作。

基本类型:

byte short int long double float char boolean

包装类型:

Byte Short Integer Long Double Float Character Boolean

包装类用法基本是相似的,因此只要找一个常用的作为代表来学习即可----Integer。

特点:

这8个类都是final类,不能有子类。

只有字符类型有一个构造方法,来创建对象,其他对是两个与Integer类似。

以Integer为例

        
        Integer i = new Integer(1);     //int类型
        System.out.println(i);
        Integer i1 = new Integer("110");    //字符串类型,字符串内容必须是int类型的,否则会抛出数字格式化异常
        System.out.println(i1);

格式之间的转换:

xxxValue(): 将对象转为xxx的基本类型

parseXxx(): 将字符串转为xxx的基本类型 Character类没有该方法

        Integer i = new Integer(1);         
        int a =i.intValue();        //intValue() 将对象转换为int类型
        System.out.println(a);
​
        String s = "abc";
        int b = Integer.parseInt(s);    //parseInt() 将字符串转换为int类型
        System.out.println(b);

1.字符串转换成包装类 1)可以使用包装类中的构造函数进行转换。 Integer(String s) 构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值 Integer i1=new Integer("123"); 2)可以使用包装类中的valueOf()方法。 static Integer valueOf(String s) 返回保存指定的 String 的值的 Integer 对象。 Integer i2=Integer.valueOf("123");

2. 包装类转换成字符串

1)使用包装类的toString()方法; String s=Integer.toString();

3. 字符串转换成基本数据类型

1)字符串转成基本类型使用包装类中的parseXxxx方法。 static int parseInt(String s)

将字符串参数作为有符号的十进制整数进行解析。Character类没有这个方法

4. 基本数据类型转换成字符串类型 1)可以直接使用+号 String s=123+""; 2)使用String类中的valueOf static String valueOf(int i) 返回 int 参数的字符串表示形式。 String s=String.valueOf(int i);

注意:String参数一定要与被创建对象的格式是一致的,否则出现格式化异常。

例如: 将”11a”封装成Integer对象,出现NumberFormatException

Boolean对象创建是,参数是String的,参数值只要是true(忽略大小写),最终将

true封装成对象,其他字符串值都是false封装成对象。

总结:

int 、String、 Integer三者间转换:

int--->String : int+””

String.valueOf(int)

String---> int: Integer.parseInt(str)

int--->Integer : new Integer(int)

Integer.valurOf(int)

Integer---->int: intValue()

String---->Integer : new Integer(str)

Integer.valueOf(str)

Integer---->String : new Integer().toString()

谁变Integer :方法1 ---> new Integer(谁)

方法2 ---> Integer.ValueOf(谁)

谁变String :方法1 ---> .toString

方法2 ---> String.valueOf(谁)

方法3 ---> 基本类型+“”

谁变int : Integer.parseInt(str) 字符串

int: intValue() nteger

JDK5.0特性:

自动装箱和自动拆箱:

装箱:将基本类型转为包装类对象形式

拆箱:将包装类对象转为基本类型

自动装箱: 可以将基本类型数据直接赋值给包装类对象, new Integer()

自动拆箱: 可以将包装类对象直接赋值给基本类型变量, intValue()

好处:简化代码的书写

弊端:大量使用可能会对性能有损耗,因此不建议过多使用

4.System类

java.lang包中,final类,系统类,类中成员是静态的,该类不能实例化。

属性:

out: 标准的输出数据,默认输出位置是控制台,可以改。

in :标准的输入数据,默认是通过键盘进行输入,可以改。

err: 标准的错误数据输出,用法out相同,输出位置也是控制台,输出内容位置会移动。

方法:

long currentTimeMillis(): 获取当前系统时间毫秒值,从1970-1-1 0:0:0开始计算的。

1s = 1000ms

void exit(int status) :jvm终止执行。status是状态码,非0数字代表异常退出。

5.Math

java.lang包中,final类,类中封装了常用的一些基本数学计算,如三角函数、对数等。

类中成员都是静态的。

属性:

PI:圆周率

E: 自然底数

6.大数据类型

java.math包中。

BigInteger:

基本类型:long类型 8个字节

遇到的数据超出long范围,使用BigInteger来表示。

BigInteger b1 = new BigInteger("11");
//返回类型是一个BigInteger类型的

BigDecimal:

double、float 应用领域:科学记数或工业领域,都是近似数。

该类是一个不可变的有精确的表示小数

构造方法:

BigDecimal(String num) : 常用

BigDecimal(double num) : 可能出现不可预知的结果,因此不建议使用

将double数据转为字符串,再封装到BigDecimal对象中

7.日期对象

java.util包。

Date:

表示特定的瞬间,能精确到毫秒。

该类中的大部分方法都是已过时方法,有对应的替代。

方法

//无参数构造方法
Date date =new Date();
System.out.println(date);
//Fri Jul 09 20:40:38 GMT+08:00 2021
​
//带参构造方法
Date date =new Date(45646154165l);      //意思是起始时间1970/1/1 加上这么多毫秒
System.out.println(date);
//Sun Jun 13 15:29:14 GMT+08:00 1971
​
//setTime       表示1970/1/1 以后的多少毫秒以后的时间
date.setTime(45746164500l);
System.out.println(date);
​
//getTime       表示现在距离到1970/1/1过了多少
long a = date.getTime();
System.out.println(a);

Dateformat

Date date =new Date(45646154165l);
DateFormat df = DateFormat.getDateInstance();       //DateFormat.getDateInstance()创建一个实例对象
String ss = df.format(date);        //.format将date转为String类型
System.out.println(ss);         //1971-6-13
​
​
Date time = df.parse(ss);       //.parse 将String转为Date
System.out.println(time);       //Sun Jun 13 00:00:00 GMT+08:00 1971
​
getInstance() 这个函数得到的最终结果是简短的

SimpleDateFormat:

对日期进行格式化,允许使用自己指定的模式

Date date =new Date();      //无参构造
SimpleDateFormat sdf = new SimpleDateFormat();
String s = sdf.format(date);    //将Date值格式化
System.out.println(s);      //输出是默认值    21-7-9 下午9:13
​
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E"); //自定义格式
String s1 = sdf1.format(date);      //将Date值格式化为自定义的格式
System.out.println(s1);         //输出指定格式    2021年07月09日 09:13:42 星期五

SimpleDateFormat:格式化和解析日期

1.格式化(Date 到 String ) : format(Date date)

2.解析(String 到 Date) : parse

8.日历对象

在java.util包中。

Calendar:

该对象将Date类中的大部分方法替代了。该对象封装有关系时间日期信息很详细。

获取Calendar对象:

static getInstance()

方法:

int get(字段) :根据字段获取字段值,字段:年、月、日...

Calendar c = Calendar.getInstance();        //创建日历对象
System.out.println(c.get(Calendar.YEAR));   //get 方法获取字段年
​
c.set(Calendar.YEAR,2022);      //set 方法设置字段值
​
long l = c.getTimeInMillis();       //获取毫秒值
System.out.println(l);

总结

1.Date和Calendar互转

(1) Calendar转化为Date ​ Calendar cal=Calendar.getInstance(); ​ Date date=cal.getTime();

(2) Date转化为Calendar ​ Date date=new Date(); ​ Calendar cal=Calendar.getInstance(); ​ cal.setTime(date);

2.获取毫秒的方法;

a.System currentTimeMillis()

b.new Date().getTime

c.c.getTimeInMillis() c是日期的一个实例化

NumberFormat

NumberFormat nf =NumberFormat.getInstance();        //创建一个实例化对象
nf.setMaximumIntegerDigits(2);      //设置格式化格式
String s1 = nf.format(202.12);      //开始格式化
System.out.println(s1);         //02.12

9.异常

概念:

程序执行过程中出现了不正常情况,导致程序停止运行了。

不正常:代码出错了

理解

异常也是对象,对象封装了代码错误的原因、位置、名称等相关信息。

异常也是一种处理异常的机制,包括:捕获、抛出、跳转等。

异常不同,对象不同,因此有一个继承体系(java.lang):

根类:

Throwable:

--Error :错误,比较严重的问题,不建议去捕获或处理。

--Exception:异常,比较不太严重的问题,建议去捕获处理。

异常(Exception)分类:

编译时异常(受检时异常):在编译时就检测的异常,必须处理后才能去执行。说明程序可能出现异常,但是不一定真的会出现异常

Exception中除了RuntimeException以外的异常。

运行时异常(非受检时异常):在运行时去检查,出现问题后停止执行,并将信息打印。

RuntimeException及其RuntimeException的子类

jvm默认处理异常的方式:

当执行到某行时,该行代码有问题,会找到异常体系中的一个对象来封装该问题,首先先尝试内部解决,能解决就解决,不能解决就交给调用者即上一级,上一级接到问题后,也是先尝试自己解决,能解决就解决,不能解决就交给调用者即上一级,...以此类推,最终交给jvm,jvm也会尝试自己解决,不能解决就采用默认处理方案,将异常问题等信息打印,并终止程序的执行。

异常处理:

1.捕获 自己解决

2.声明 找上一级

捕获

try{}: 可能出现异常的代码

catch{}: 处理异常代码

finally{}: 一定会执行的代码,作用用来做释放资源的操作。

常用方法:getCause(): 获取属性cause的信息,如果不存在返回null

getMessage():获取属性message的值

toString(): 返回throwable的简短描述

printStackTrace():打印输出Throwable的跟踪信息

格式1:

try{

}catch(异常类型名 变量名){

}

try中有异常,会有一个异常对象产生,将异常对象交给catch,catch接到后与小阔号中的异常类型进行匹配,匹配上就处理异常,如果没有匹配上就jvm默认处理。

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

        System.out.println("开始");
        try {
            method();									//调用方法出现异常
        }catch (ArrayIndexOutOfBoundsException e ){
//            System.out.println("假装处理了");
            e.printStackTrace();		//打印异常信息,虽然也会出现异常,但是程序在出现异常后不会停止
        }
        System.out.println("结束");
    }
	
    //创建方法
    public static void method(){
        int[] arr = {1,2,3};
        System.out.println(arr[3]);
    }
}

        e.printStackTrace();		//异常信息输出在控制台
        e.getMessage();				//返回详细消息字符串
        e.toString();				//抛出简短描述

格式2:

try{

}catch(异常类型1 变量名1){

}catch(异常类型2 变量名2){

}...

try中有异常,会有一个异常对象产生,将异常对象交给catch,catch接到后与小阔号中的异常类型1进行匹配,匹配上就处理异常,整个语句块结束,执行try-catch后的代码,如果没有匹配上,与异常类型2进行匹配,....所有异常类型都没有匹配,jvm默认处理。

注意:catch小阔号中的异常类型,有父子关系,那么先写子后写父。如果没有父子关系即是兄弟关系,没有顺序之分。总结:从上往下看,类型可以逐渐变大或者不变。

格式3:

try{

}catch(){

}...

finally{

}

一个try一个catch一个finally

一个try多个catch一个finally

try中无论是否有异常,finally一定会执行。

即使遇到return;语句,finally也一定会执行。

只有一种情况,finally不执行,遇到System.ext(0);

格式4:

try{

}finally{

}

这种语句格式目的就是为了使用finally,因为finally不能独立出现。

catch中的代码:

只要是符合java的语法都可以,但是实际是什么问题什么解决方案。

比如: 语句、调用方法、创建对象

try-catch是允许嵌套使用的。

自定义异常

原因:

1.异常体系太庞大,不方便记忆和使用

2.异常体系中没有所需要的异常

步骤:

1.定义类继承Exception或RuntimeException

类名: 异常原因名+Exception

2.调用父类的构造方法(可选)

重写方法时,throws注意

\1. 重写方法时,父类方法没有throws,子类重写时可以不带有,如果带有throws,其后边只能跟RuntimeException,可以写多个

\2. 重写方法时,父类方法有throws,子类重写没有throws可以,如共有throws,只要是父类异常的子集或相同都可以。

总结:重写方法,可以没有throws,如果有throws范围只要不超过父类异常即可

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值