静态资源:static关键字
特点:
1、 可以修饰成员变量,成员方法
2、 随着类的加载而加载,优先于对象加载
3、 只加载一次,就会一直存在,不再开辟新空间
4、 全局唯一,全局共享
5、 可以直接被类名调用
6、 静态只能调用静态,非静态可以随意调用
7、 static不能和this或者super共用,因为有static时可能还没有对象
//测试 static
public class Test1_Static {
public static void main(String[] args) {
//3,如何调用静态资源呢? -- 静态资源多了一种调用方式,可以类名直接调用
//4,随着类的加载而加载,优先于对象加载
Person.test();
System.out.println( Person.age );
//TODO 创建对象测试
Person p = new Person();
p.show();
System.out.println( p.name );
//2,如何调用静态资源呢? -- 通过对象访问
p.test();
System.out.println( p.age );
//5,静态资源是共享资源,在多个对象间数据共享
Person p2 = new Person();
Person p3 = new Person();
p2.age = 10 ;
System.out.println( p3.age );//10,age在p2和p3间共享
}
}
class Person{
//静态资源
//1,static 可以用来修饰成员变量和成员方法
static int age;
static public void test() {
//this.show();--Cannot use this in a static context
//super. --Cannot use this in a static context
//7, 静态资源 可以调用 普通资源吗? -- 不可以-静态只能调用静态
// show();
// System.out.println(name);
System.out.println("test()...");
}
//普通资源
String name ;
public void show() {
//6,普通资源 可以调用 静态资源吗? -- 可以
test();
System.out.println(age);
System.out.println("show()...");
}
}
静态代码块、构造代码块、局部代码块的区别
–1,静态代码块通常用于完成项目的初始化.
–2,静态资源会随着类的加载而加载,第一时间加载进内存,并一直贮存在内存中,直到类消失静态资源才消失.
–3,静态资源只会被加载一次
–4,静态代码块,存在的位置是成员位置.如:static {. . . . };
//测试 代码块
//总结
//静态代码块 --位置:在成员位置--作用:完成项目初始化--触发节点:类加载时
//构造代码块 --位置:在成员位置--作用:抽取构造方法的共性--触发节点:创建对象时
//局部代码块 --位置:在局部位置--作用:控制变量的作用范围--触发节点:方法执行时
//执行顺序:静态代码块 > 构造代码块 > 局部代码块
public class Test2_Block {
public static void main(String[] args) {
//静态代码块首先输出且只输出一次,直到类执行完毕;
new BlockDemo();//触发了构造代码块和构造方法
new BlockDemo();
new BlockDemo().test();//触发了构造代码块和构造方法和局部代码块
}
}
class BlockDemo{
//静态代码块
static{
System.out.println("静态代码块");
}
//构造代码块
{
System.out.println("构造代码块");
}
//构造方法
public BlockDemo() {
System.out.println("构造方法");
}
//局部代码块
public void test() {
{
System.out.println("局部代码块");
}
}
}
final关键字
在继承结构中,父类的功能可以全都给子类用.但是当子类想要修改功能 时,会发生方法的重写现象.子类想改哪个方法都可以重写.如果想要限制,不让子类随便重写.可以把父类的功能用final修饰成最终的;
//测试 final关键字
public class Test3_Final {
public static void main(String[] args) {
Zi zi = new Zi();
zi.eat();//重写前使用了父类的功能,重写后使用子类的功能
//zi.age = 20;//修改了age的值
System.out.println(zi.age);//使用了age的值
}
}
//1,final修饰类不能被继承--The type Zi cannot subclass the final class Fu
//final class Fu{
class Fu{
//2,final修饰方法可以被继承,但是不能被重写--Cannot override the final method from Fu
final public void eat() {
System.out.println("Fu...eat()...");
}
//3,final修饰的是常量,值不能被修改--The final field Fu.age cannot be assigned
final int age = 1_000 ;
}
class Zi extends Fu{
/*
* //需要修改父类原有的功能--方法重写--方法声明必须和父类一模一样
* @Override
* public void eat() { System.out.println("Zi...eat()"); }
*/
}
多态
概念:–1,多态是指同一个对象有多种形态.
–2,多态是为了统一调用标准—父类就是标准,一切向父类看齐
–3,好处是:不关心具体的类型,屏蔽了子类之间的不同,把子类都会当做父类来看.
做出统一的编程,写出通用的代码.提高了程序的灵活性和扩展性;
–4,特点:
–前提: 发生继承关系 + 发生方法重写
–口诀: 父类引用指向子类对象 + 编译看左边运行看右边
//测试 多态
public class Test4_Multi {
public static void main(String[] args) {
//TODO 创建子类对象测试
Dog d = new Dog();
d.eat();//重写了,用了子类的
//TODO 创建多态对象测试
//口诀1:父类引用 指向 子类对象-相当于把子类转成父类
Animal a = new Dog();
//口诀2:编译看左边,运行看右边
a.eat();//使用了父类的方法声明,使用了子类的方法体
//编译看左边 -- 是指 想要成功的保存,就要使用左边也就是 只能使用父类提供的功能!!
//运行看右边 -- 是指 想要得到结果,就要看右边也就是 使用子类的方法体!!!
//静态方法可以重写吗 --- 不可以!!
a.show();//使用了父类的方法声明 和 方法体
Animal.show();//静态资源,谁调用就执行谁的功能,根本没有重写的说法!!
}
}
class Animal{
public void eat() {
System.out.println("哥斯拉吃奥特曼");
}
static public void show() {
System.out.println("Father...show()");
}
}
//1,多态的前提1:发生继承关系
class Dog extends Animal{
//2,多态的前提3:发生方法重写
@Override
public void eat() {
System.out.println("吃狗粮");
}
static public void show() {
System.out.println("Son...show()");
}
}
向上转型与向下转型
在应用中就存在着两种转型方式,分别是:向上转型和向下转型。
比如:父类Parent,子类Child
**向上转型:**父类的引用指向子类对象Parent p=new Child( );
说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类的方法就根据这个引用指向调用子类重写方法。
**向下转型(较少):**子类的引用的指向子类对象,过程中必须要采取到强制转型。
Parent p = new Child( );//向上转型,此时,p是Parent类型
Child c = (Child) p ;//此时,把Parent类型的p转成小类型Child
//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。
异常
–1,异常是指程序中出现的Bug.
–2,继承结构非常严谨,Throwable-Exception-…
–3,Exception是程序中所有异常的父类
–4,异常处理
–捕获:把程序中会出现的异常自己处理掉
try{
代码
}catch(异常类型1 异常名){
给出解决方案1
}catch(异常类型2 异常名){
给出解决方案2
}
–抛出:把程序中出现的异常自己不管,交给调用者去管
//测试 异常
public class Test6_Exception {
public static void main(String[] args) {
// method() ; //暴露异常
method2() ; //异常处理!!!--捕获异常
}
//捕获异常
private static void method2() {
try {//尝试执行try里的代码
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a/b);
}catch(ArithmeticException a) {//如果分母为0了立刻捕获
System.out.println("两次输入不能为0!");
}catch(InputMismatchException a) {//如果类型不对了立刻捕获
System.out.println("请输入两次整数!");
}catch(Exception a) {//如果有其他异常立刻捕获
//多态的好处:不关心具体的子类类型,把子类当父类来看。写出通用代码
System.out.println("请输入正确的数据!");
}
//现在的问题是:程序中也许不仅仅只有两种异常,还可能有更多异常
//但是,我根本不知道还有几个异常,异常的名字叫什么???? ---所以可以直接用所有异常的父类Exception
}
//暴露异常
public static void method() {
//接收键盘输入的两个整数
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
//做除法运算
System.out.println(a/b);
}
}
抛出:自己不处理,谁调用谁处理
–在方法声明上添加代码 ,如: throws 异常类型
// 测试 抛出异常
public class Test1_Exception {
// public static void main(String[] args) throws Exception{
public static void main(String[] args){
// method();//暴露异常
try {
method2();
}catch(Exception e){
//3,method2抛出异常自己没管,调用者来处理抛出的异常Exception
System.out.println("运算异常!!");
}
}
//1,抛出异常--在方法声明上添加throws 异常类型1,异常类型2
public static void method2()
// throws ArithmeticException,InputMismatchException,?, ?{
throws Exception{
//2,多态,根本就不关心具体的异常类型,都会把子类当父类来看
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a/b);
}
//暴露异常
public static void method() {
//接收键盘输入的两个整数
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
//做除法运算
System.out.println(a/b);
}
}