01

    科技2022-07-16  138

    static-静态的final-最终的abstract-抽象的interface-接口随着类的加载而加载类不能被继承类不能被实例化不能实例化共享一份方法不能被重写提供子类变量不能被修改

    1 关键字:static

    ① 总结

    static:静态的!①随着类的加载而加载;②共享~

    static可以用来修饰:属性、方法、代码块、内部类

    使用static修饰属性:静态变量(或类变量)

    属性:按是否使用static修饰,又分为:静态属性 VS 非静态属性(实例变量)

    非静态属性:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象的静态变量,不会导致其中对象中同样的属性值的修改。静态变量:我们创建了类的多个对象,多个对象共享一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。

    static修饰属性的其他说明:

    静态变量随着类的加载而加载。可以通过”类.静态变量“的方式进行调用。

    静态变量的加载要早于对象的创建。

    由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法去的静态域中。

    ​ 类变量 实例变量

    类 yes no

    对象 yes no

    静态属性举例:System.out;Math.PI

    使用static修饰方法:静态方法

    随着类的加载而加载,可以通过”类.静态方法“的方式进行调用

    ​ 静态方法 非静态方法

    ​ 类 yes no

    ​ 对象 yes yes

    静态方法中,只能调用静态的方法或属性(比如main方法中能调用静态的方法和属性。)

    非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性

    static注意点:

    在静态方法内,不能使用this关键字、super关键字(这是因为静态方法随类一起创建,而this和super都是对象)关于静态属性和静态方法的使用,要从生命周期的角度去理解:

    开发中,如何确认一个属性是否需要声明为static呢?

    属性是可以被多个对象所共享的,不会随着对象的不同而不同的!类中的常量也常常声明为static

    开发中,如何确认一个方法是否需要声明为static呢?

    操作静态属性的方法,通常设置为static的工具类中的方法,习惯上声明为static的。比如:Math、Arrays、Collections

    ② 类变量的加载内存解析

    共享~

    ③ Static使用举例1

    public class Circle { private double radius;//半径 private int id;//圆的编号,自动赋值 private static int total;//记录创建圆的个数 private static int init = 1001;//static声明的属性被所对象共享 public Circle() { id = init++; total ++ ; } public Circle(double radius) { this(); // id = init++; // total++; this.radius = radius; } //计算圆的面积 public double findArea(){ return Math.PI*radius*radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public int getId() { return id; } public static int getTotal() { return total; } }

    ④Static举例2(单例模式)重点!!!

    概念

    单例设计模式,就是采取一定方法保证在整个软件系统中,对某个类只有一个对象实例。

    饿汉式: 缺点:对象加载时间过长优点:饿汉式是线程安全的 懒汉式: 优点:延迟对象的创建缺点:目前的写法,线程是不安全的——>到多线程内容时解决。

    饿汉式

    public class Bank{ //1.私有化类的构造器 private Bank(){ } //2.内部创建类的对象 //4.要求此对象也必须声明为静态的 private static Bank bank = new Bank(); //3.提供公共的静态方法,返回类的对象 private static Bank getBank(){ return bank; } }

    懒汉式

    要实例化一个对象的时候,再去实例化。

    public class Order{ //1.私有化类的构造器 private Order(){ } //2.声明当前类的对象,没初始化 //4.要求此对象也必须声明为静态的 private static Order instance = null; //3.声明public、static的返回当前类对象的方法 public static Order getInstance(){ if(instance == null){ instance = new Order(); } return instance; } }

    2 理解main方法的语法

    总结

    mian()方法作为程序的入口main()方法也是一个普通的静态方法main()方法可以作为与控制台的交互方式 public static void main(String[] args){} ①权限修饰符:public protected 缺省 private ②修饰符:static final abstract native ③返回值类型:void无返回值 有返回值return ④方法名:满足标识符命名规则、规范 ⑤形参列表:重载 vs 重写 ;参数的值传递机制 ; 多态性; 数组 ⑥方法体:体现方法的功能

    3 类的成员:代码块

    类的成员:属性、方法、构造器、代码块、内部类

    ①概念

    代码块的作用:用来初始化类、对象的信息

    ②分类

    分类:是否用static修饰:静态代码块 vs 非静态代码块 静态代码块: 随着类的加载而执行,而且只执行一次作用:初始化类的信息静态代码块只能调用静态的属性、静态的方法,不能调用非静态的结构 非静态代码块: 随着对象的创建而执行,每创建一个对象就会执行一次非静态代码块作用:在创建对象时,对对象的属性进行初始化非静态代码块可以调用静态的属性、静态的方法,或非静态的属性和方法。

    4 关键字:final最终的

    final可以用来修饰:类、方法、变量

    final用来修饰一个类:此类不能够被其它类所继承final用来修饰方法:表示类不能够被重写final用来修饰变量:此时的变量就是一个常量,不可以重新赋值 static final 用来修饰属性,表示全局常量

    5 抽象类和抽象方法:abstract

    abstract可以用来修饰:类、方法

    抽象类: 此类不能够实例化抽象类中一定由构造器,便于子类实例化时调用开发中,都会提供抽象类的子类,让子类对象实例化,完成相关操作 抽象方法: 抽象方法只有方法的声明,没有方法体{}包含抽象方法的类,一定是抽象类;反之抽象类中可以没有抽象方法若子类重写了父类中的抽象方法,此子类可以实例化若子类没有重写父类的抽象方法,那么子类必须为一个抽象类,不然报错。 public abstract class Vehicle{ public abstract double calcFuelEfficiency();//计算燃料效率的抽象方法 public abstract double calcTripDistance();//计算行驶距离的抽象方法 } public class Truck extends Vehicle{ @Override//重写计算卡车的燃料效率的具体方法 public double calcFuelEfficiency() { return 0; } @Override//重写计算卡车行驶距离的具体方法 public double calcTripDistance() { return 0; } }

    6 接口(interface)

    ①总结

    接口使用interface来定义在Java中接口和类是并列的两个结构如何定义接口:定义接口的成员 JDK7及以前:只能定义全局常量和抽象方法 全局常量:public static final的,可以省略不写抽象方法:public abstract的 JDK8:除了定义全局常量和抽象方法外,还可以定义静态方法、默认方法 接口中不能定义构造器,意味着接口不可以实例化Java开发中,接口通过让类其实现implements的方式来使用 如果实现类覆盖了接口中的所有抽象方法,则实现类一定能够实例化如果实现类没有覆盖接口中所有的抽象方法,则实现类仍为一个抽象类 Java类可以实现多个接口 ——> 弥补Java单继承性的局限性 格式:class AA extends BB implements CC, DD, EE 接口和接口之间可以继承,而且可以多继承接口的具体使用,体现了多态性接口,实际上可以看做一种规范;面向接口编程。

    ②Java8关于接口的新规范

    接口中定义的静态方法,只能通过接口来调用

    通过实现类的对象,可以调用接口中的默认方法。

    如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那子类在没重写此方法的情况下,默认调用的是父类中的同名同参数的方法。——>类优先原则

    如果实现类实现了多个接口,而多个接口中定义了同名同参数的默认方法,那么在实现类没重写此方法的情况下,报错。——>接口冲突

    如何在子类(或实现类)的方法中调用父类接口被重写的方法

    当父类和父接口出现重名的属性,那么调用同名的属性必须做出选择,不然就报错! 可以使用Super.属性,调用父类中的同名属性。可以使用父接口名.属性,调用父接口中的同名属性。这是因为接口中的属性都是静态常量。 public void myMethod(){ method3();//调用自己定义的重写的方法 super.method3();//调用的是父类中声明的 //调用接口中的默认方法 CompareA.super.method3(); CompareB.super.method3(); }

    ③案例

    //测试类Computer public class Computer { public void transferDate(USB usb){ System.out.println("开启:"+usb.start()); System.out.println("具体的传输数据细节"); System.out.println("关闭:"+usb.stop()); } public static void main(String[] args) { Computer computer = new Computer();//要调用传输数据方法就得造一个computer computer.transferDate(new Printer());//往computer的传输数据方法内放一个打印机对象 } } //接口USB public interface USB { public abstract int start();//接口中的抽象方法 int stop();//可以省略public abstract } //接口USB的实现类Flash public class Flash implements USB{ @Override public int start() { return 1; } @Override public int stop() { return 2; } } //接口USB的实现类Printer public class Printer implements USB{ @Override public int start() { return 11; } @Override public int stop() { return 12; } }

    ④抽象类和接口的异同

    相同点:都不能实例化,都可以包含抽象方法不同点: 定义,内部结构不同抽象类是类,单继承性;接口多继承性

    7 类的成员:内部类

    匿名内部类

    如果有些子类或实现类,只使用一次,那么去单独为其创建java文件也挺麻烦的,可以使用匿名内部类,去解决这一问题。

    public class PlaneTest { public static void main(String[] args) { //如果子类只使用一次,那么可以创建匿名内部类,也就不用再创建一个子类单独的java文件 //不过和创建子类文件一样都要重写其内部的abstract的抽象方法。 //这体现了多态的性质,父类的对象指向子类。 Traffic t1 = new Traffic() { @Override public void transport() { System.out.println("t1...transport..."); } }; //多态,父类的对象,看运行时,是子类重写的方法。 t1.transport(); //接口也是同样的道理。 Fly fly = new Fly(){ @Override public void fly() { } }; } }

    ①定义

    Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类

    ②分类

    成员内部类(静态、非静态)

    一方面作为外部类的成员: 调用外部类的结构可以被static修饰可以被4种不同的权限修饰 另一方面,作为一个类: 类内可以定义属性、方法、构造器可以被final修饰,表示不可以被继承可以被abstract修饰

    局部内部类(方法内、代码块内)

    ③成员内部类的使用

    4.1如何创建成员内部类的对象?(静态的,非静态的) //创建静态的Dog内部类的实例(静态的成员内部类): Person.Dog dog = new Person.Dog(); //创建非静态的Bird内部类的实例(非静态的成员内部类): //Person.Bird bird = new Person.Bird();//错误的 Person p = new Person(); Person.Bird bird = p.new Bird(); 4.2如何在成员内部类中调用外部类的结构? class Person{ String name = "小明"; public void eat(){ } //非静态成员内部类 class Bird{ String name = "杜鹃"; public void display(String name){ System.out.println(name);//方法的形参 System.out.println(this.name);//内部类的属性 System.out.println(Person.this.name);//外部类的属性 //Person.this.eat(); } } }

    ④局部内部类的使用

    //返回一个实现了Comparable接口的类的对象 public Comparable getComparable(){ //创建一个实现了Comparable接口的类:局部内部类 //方式一: // class MyComparable implements Comparable{ // // @Override // public int compareTo(Object o) { // return 0; // } // // } // // return new MyComparable(); //方式二: return new Comparable(){ @Override public int compareTo(Object o) { return 0; } }; }

    注意点: 在局部内部类的方法中(比如:show如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,要求此局部变量声明为final的。

    public class InnerClassTest{ public void method(){ //局部变量 int num = 10; class AA{ public void show(){ //num = 20;//错误!!默认num为final的 System.out.println(num);//输出10 } } } }

    总结: 成员内部类和局部内部类,在编译以后,都会生成字节码文件。 格式:成员内部类:外部类$内部类名.class

    局部内部类:外部类$数字 内部类名.class

    8 练习

    ①练习1

    测试类:

    package www.atguigu.exer1; /** * @author:Ven * @date:2020/8/9 - 15:56 * @function: */ public class AccountTest { public static void main(String[] args) { Account account = new Account("112341", 2000); Account account1 = new Account(); Account.setRate(0.012); Account.setMinMoney(100); System.out.println(account); System.out.println(account1); System.out.println(account.getRate()); System.out.println(account.getMinMoney()); } }

    Account类

    package www.atguigu.exer1; /** * @author:Ven * @date:2020/8/9 - 15:45 * @function: */ public class Account { private int id; private String pwd = "000000"; private double balance; private static double rate; private static double minMoney = 1.0; private static int init=1001; public Account() { id = init++; } public Account(String pwd, double balance) { this(); this.pwd = pwd; this.balance = balance; } public int getId() { return id; } public double getBalance() { return balance; } public static double getRate() { return rate; } public static double getMinMoney() { return minMoney; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public static void setRate(double rate) { Account.rate = rate; } public static void setMinMoney(double minMoney) { Account.minMoney = minMoney; } @Override public String toString() { return "Account [id="+id+", pwd="+pwd+", balance="+balance+"]"; } }

    ②练习2

    public abstract class Employee { private String name; private int id; private double salary; // private static int init=001; public Employee() { // id = init++; } public Employee(String name, int id, double salary) { this.name = name; this.id = id; this.salary = salary; } public abstract void work(); } public class Manager extends Employee{ private double bonus; public Manager(double bonus) { this.bonus = bonus; } public Manager(String name, int id, double salary, double bonus) { super(name, id, salary); this.bonus = bonus; } @Override public void work() { System.out.println("我是一个Manager"); } } public class CommonEmployee extends Employee{ @Override public void work() { System.out.println("我是CommonEmployee"); } } public class EmployeeTest { public static void main(String[] args) { //多态 Employee manager = new Manager("库克", 1001,5000, 50000); manager.work(); CommonEmployee commonEmployee = new CommonEmployee(); commonEmployee.work(); } }
    Processed: 0.009, SQL: 8