1 static

1.1 概念

是java中的一个关键字
用于修饰成员(成员变量和成员方法)

1.2 特点

  1. 随着类的加载而加载
  2. 只加载一次,就会一直存在,直到类消失就一起消失了
  3. 优先于对象加载
  4. 被所有对象所共享
  5. 可以<mark>直接被类名调用</mark>

1.3 练习1:入门案例

创建day07工程
创建cn.tedu.staticdemo包
创建Test1_Static.java

package cn.tedu.staticdemo;
//这个类用来测试static的使用
public class Test1_Static {
       public static void main(String[] args) {
         	//1、随着类的加载而加载,没有也可以
			//2、静态资源可以被类名直接调用
			System.out.println(Person.name);
			//TODO 创建Person对象测试
			Person p = new Person();
			p.name="rose";
			p.eat();
			System.out.println(p.name);
			Person p2 = new Person();
			//3、静态资源在所有对象间都是共享的,p修改后,p2能够看到改后的数据
			System.out.println(p2.name);
	}
}

//创建Person类

class Person{
	static String name = "jack";
	public void eat() {
		System.out.println("正在吃饭");
	}
}

1.4 [了解]静态内存图

1.5 练习2:静态调用关系

package cn.tedu.staticdemo;

 

//这个类用来测试static的调用关系

//总结:1、静态只能 调 静态

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

//创建Animal类

class Animal{
    //普通资源 -- 调用啥都行(静态/非静态)
    String name;
    public void eat() {
       //普通资源 调用 静态资源 -- 能
       sleep();
       //普通资源 调用 普通资源 -- 能
       System.out.println(name);
       System.out.println("正在吃饭");
    }
    //静态资源 -- 只能调用 静态资源
    static int age;
    static public void sleep() {
       //静态资源 调用 普通资源 -- 不能
// System.out.println(name);
       //静态资源 调用 静态资源 -- 能
       System.out.println(age);
       System.out.println("正在睡觉");
    }
}

2 静态代码块、构造代码块、局部代码块

static {

}

  1. 静态代码块:在类加载时就加载,并且<mark>只被加载一次</mark>,一般用于项目的初始化
  2. 构造代码块:在创建对象时会自动调用,每次创建对象都会被调用
  3. 局部代码块:方法里的代码块
package cn.tedu.staticdemo;
//测试三种代码块的执行顺序
//1、 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化
//2、 构造代码块:在创建对象时会自动调用,每次创建对象都会被调用
//3、 局部代码块:方法里的代码块
public class Test3_Block {
    public static void main(String[] args) {
       //创建Teacher对象
        Teacher t = new Teacher();
       Teacher t2 = new Teacher();
//t: 静态代码块
//t: 构造代码块
//t: 构造方法 
//t2: 构造代码块
//t2: 构造方法 
       t.eat();//局部代码块
       t.eat();//局部代码块
    }
}
//创建类
class Teacher{
    //构造代码块:创建对象时用,常用于提取构造方法的共性
    {
       System.out.println("构造代码块");
    }
    //构造方法,常用于创建对象
    public Teacher() {
       System.out.println("构造方法");
    }
    //静态代码块:类加载就用,常用于功能的初始化,只加载一次!
    static {
       System.out.println("静态代码块");
    }
    public void eat() {
       //局部代码块:方法调用时才用,常用于控制变量的范围
       {
           System.out.println("局部代码块");
       }
    }
}

3 final

3.1 概念

  1. 是java提供的一个关键字
  2. final是最终的意思
  3. final可以修饰类,方法,成员变量
    初衷是因为:java出现了继承后,子类可以更改父类的功能,当父类功能不许子类改变时可以利用final关键字修饰父类。

3.2 特点

  1. <mark>被final修饰的类,不能被继承</mark>
  2. <mark>被final修饰的方法,不能被重写</mark>
  3. 被final修饰的变量是个常量,不能被改变
  4. 常量的定义形式:final 数据类型 常量名 = 值

3.3 入门案例

package cn.tedu.finaldemo;
//这个类用来测试final关键字
public class Test4_Final {
    public static void main(String[] args) {
       //创建父类对象测试
       Fu f = new Fu();
       f.age=20;
    }
}

//创建父类
//1、final修饰的类,不能被继承
//final class Fu{
class Fu{ 
//2、final修饰的变量,值不能被修改,是个常量
// final int age = 10;
    int age  = 10;
   //3、final修饰方法,不能被重写!
// final public void eat() {
    public void eat() {
       System.out.println("爸爸在吃饭");
    }
}
//创建子类
class Zi extends Fu{
    //重写
    public void eat() {
       System.out.println("儿子在吃饭");
    }
}

4 多态 OOP

4.1 概念

多态指同一个实体同时具有多种形式。
它是面向对象程序设计(OOP)的一个重要特征。
主要是指同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
好处是:可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,<mark>统一调用标准</mark>。

例子:狗有两种形态:狗和小动物

class Animal{

}

class Dog extends Animal{

}

 

class Test1{

    main(){

       Dog d = new Dog();//小狗是小狗

       Animal a = new Dog();//小狗是小动物,多态

    }

}

4.2 特点

  1. 多态的前提1是继承
  2. 多态的前提2要有方法的重写
  3. <mark>父类引用指向子类对象 如:Animal a = new Dog(); – 小到大,向上转型</mark>(非常常见)
  4. 多态中,编译看左边,运行看右边

4.3 入门案例

package cn.tedu.duotai;

 

//这个类用来测试多态的入门案例

public class Test5_Duotai {

       public static void main(String[] args) {

              //创建父类对象测试

              Animal a = new Animal(); a.eat();//吃啥都行

              //创建子类对象测试

              Dog d = new Dog(); d.eat();//吃啥都行 -- 狗吃s(因为重写了)

             

              //TODO 创建多态对象测试

       Animal a2 = new Dog(); //1、父类引用 指向 子类对象 -- 向上造型 / 多态

              //2、编译看左边,运行看右边

       //编译看左边:只能,用父类的功能 -- 统一调用标准

       //运行看右边:干活看子类,如果重写了,就用子类的实现

              a2.eat();//狗吃s

              a2.show();

       }

}

//创建父类

class Animal{

       public void eat() {

              System.out.println("吃啥都行");

       }

       public void show() {

       }

}

//创建子类

//前提:继承+重写

class Dog extends Animal{

       //重写:方法声明一致

       public void eat() {

              System.out.println("狗吃s");

       }

}

5 多态的好处

  1. 多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法
  2. 提高了程序的扩展性和可维护性
class Animal{

    eat(Animal a){}

    //多态中,不关心具体的子类是哪种类型,子类都当做父类来看

}

class Cat extends Animal{

}

class Tiger extends Animal{

}

class Test1{

    main(){

       eat(c);

       eat(d);

       eat(t);

    }

}

6 多态的成员使用

6.1 特点

  1. 成员变量:使用的是父类的
  2. 成员方法:由于存在重写现象所以使用的是子类的
  3. 静态成员:随着对象而存在,谁调用的就返回谁的
    (理解了对象在堆里怎么存的,栈里怎么引用的,上面自然知道了)

6.2 测试

package cn.tedu.duotai;

 

//这个类用来测试多态的使用

public class Test6_Duotai2 {

    public static void main(String[] args) {

       /*//TODO 创建父类对象测试 Sharp s = new Sharp(); s.draw();//画个图形 System.out.println(s.line);//5 //TODO 创建子类对象测试 Circle c = new Circle(); c.draw();//画个图形 -- 画个圈圈(重写了...) System.out.println(c.line);//5 */

       //TODO 创建多态对象测试

       Sharp s2 = new Circle();

       s2.draw();//画个圈圈,1、多态中的成员方法,运行看右边,用子类的(发生了重写)

       System.out.println(s2.line);//5,2、多态中的成员变量,用父类的

       System.out.println(s2.name);//Sharp,3、静态资源是随着类存在的,哪个类调用就是哪个类的

    }

}

//创建父类

class Sharp{

    int line = 5;

    static String name="Sharp";

   

    public void draw() {

       System.out.println("画个图形");

    }

}

//创建子类

class Circle extends Sharp{

    int line = 10;

    static String name="Circle";

   

    //重写draw()

    public void draw() {

       System.out.println("画个圈圈");

    }

}

7 常见修饰符

8 异常

8.1 概述

用来封装错误信息的对象。
组成结构:类型,提示,行号。

8.2 异常的继承结构

 

Throwable - 顶级父类

-- Error:系统错误,无法修复

-- Exception:可修复的错误

--RunTimeException

--ClassCastException

--ClassNotFoundException

8.3 异常处理

程序中遇到了异常,通常有两种处理方式: 捕获 或者向上 抛出 。

当调用了一个抛出异常的方法时,调用位置可以不做处理继续向上抛出也可以捕获异常。

8.4 测试

package cn.tedu.exception;

 

import java.util.InputMismatchException;

import java.util.Scanner;

 

//这个类用来测试异常的处理

//处理异常的解决方案:捕获 + 抛出

public class Test7_Exception {

    public static void main(String[] args) throws Exception{

// method();// 异常的捕获

      

       //method2抛出异常,main()可以捕获也可以继续抛出

       method2();// 异常的抛出

    }

   

    // 异常的抛出:throws...异常类型1,异常类型2 或者 直接throws...Exception

// private static void method2() throws InputMismatchException,ArithmeticException{

    private static void method2() throws Exception{

       // 1、接收用户输入的两个整数a b

       int a = new Scanner(System.in).nextInt();

       int b = new Scanner(System.in).nextInt();

 

       // 2、做除法运算

       System.out.println(a / b);

    }

 

    // 异常的捕获:try....catch(异常类型 异常名){ }

    private static void method() {

       try {

           // 1、接收用户输入的两个整数a b

           int a = new Scanner(System.in).nextInt();

           int b = new Scanner(System.in).nextInt();

 

           // 2、做除法运算

           System.out.println(a / b);

 

} catch (InputMismatchException e) {// 用来捕获输入数据类型不匹配的情况

           System.out.println("请输入整数类型!");

    } catch (ArithmeticException e) {// 用来捕获输入数据分母为0的情况

           System.out.println("分母不能为0!");

} catch (Exception e) {// 多态!!不关心具体子类类型,把所有子类当父类来看,所以异常都能捕获

           System.out.println("输入错误!!!");

       }

    }

}

9 拓展

9.1 向上转型和向下转型

在JAVA中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。

<mark>在应用中就存在着两种转型方式,分别是:向上转型和向下转型。</mark>

比如:父类Parent,子类Child

<mark>向上转型:父类的引用指向子类对象Parent p=new Child();</mark>

说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类的方法就根据这个引用指向调用子类重写方法。

向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。

Parent p = new Child();//向上转型,此时,p是Parent类型

Child c = (Child)p;//此时,把Parent类型的p转成小类型Child

//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的

说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。

9.2 静态变量和实例变量的区别

<mark>在语法定义上的区别</mark>:静态变量前要加static关键字,而实例变量前则不加。

<mark>在程序运行时的区别</mark>: <mstyle mathcolor="&#35;FF3030"> </mstyle> \color{#FF3030}{实例变量} 属于某个对象的属性, <mstyle mathcolor="&#35;4285f4"> </mstyle> \color{#4285f4}{必须创建了实例对象,其中的实例变量才会被分配空间} ,才能使用这个实例变量。 <mstyle mathcolor="&#35;FF3030"> </mstyle> \color{#FF3030}{静态变量} 不属于某个实例对象,而是属于类,所以<mark>也称为类变量</mark>, <mstyle mathcolor="&#35;4285f4"> </mstyle> \color{#4285f4}{只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间} ,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
(另外,静态变量被多个相同的类共享,实例变量只属于实例的类本身)