第7章 面向对象基础-下

发布于:2024-04-23 ⋅ 阅读:(164) ⋅ 点赞:(0)

目录

7.1 静态

7.1.1 静态关键字(static)

7.1.2 静态变量

1、语法格式

2、静态变量的特点

3、静态变量内存分析

4、静态类变量和非静态实例变量、局部变量

静态方法

2、静态方法的特点

静态代码块

1、语法格式

2、静态代码块的特点

3、静态代码块和非静态代码块

类初始化

1、类初始化代码只执行一次

2、父类优先于子类初始化

3、类初始化优先于实例初始化

静态和非静态的区别

本类中的访问限制区别

2、在其他类的访问方式区别

3、this和super的使用

静态导入

枚举

JDK1.5之前

enum关键字声明枚举

枚举类的要求和特点

3、枚举类型常用方法

包装类

装箱与拆箱

包装类的一些API

基本数据类型和字符串之间的转换

、数据类型的最大最小值

3、字符转大小写

4、整数转进制

、比较的方法

包装类对象的特点

包装类缓存对象

类型转换问题

、包装类对象不可变

抽象类

语法格式

注意事项

修饰符一起使用问题?


静态方法



7.1 静态

7.1.1 静态关键字(static)

在类中声明的实例变量,其值是每一个对象独立的。但是有些成员变量的值不需要或不能每一个对象单独存储一份,即有些成员变量和当前类的对象无关。

在类中声明的实例方法,在类的外面必须要先创建对象,才能调用。但是有些方法的调用和当前类的对象无关,那么创建对象就有点麻烦了。

此时,就需要将和当前类的对象无关的成员变量、成员方法声明为静态的(static) .

大白话:就是省事才用static;

7.1.2 静态变量

1、语法格式

有static修饰的成员变量就是静态变量。

【修饰符】 class 类{
	【其他修饰符】 static 数据类型  静态变量名;
}
2、静态变量的特点
  • 静态变量的默认值规则和实例变量一样。

  • 静态变量值是所有对象共享。

  • 静态变量的值存储在方法区。

  • 静态变量在本类中,可以在任意方法、代码块、构造器中直接使用。

  • 如果权限修饰符允许,在其他类中可以通过“类名.静态变量”直接访问,也可以通过“对象.静态变量”的方式访问(但是更推荐使用类名.静态变量的方式)。

  • 静态变量的get/set方法也静态的,当局部变量与静态变量重名时,使用“类名.静态变量”进行区分。

分类 数据类型 默认值
基本类型 整数(byte,short,int,long) 0
浮点数(float,double) 0.0
字符(char) '\u0000'
布尔(boolean) false
数据类型 默认值
引用类型 数组,类,接口 null
public class Employee {
    private static int total;//这里私有化,在类的外面必须使用get/set方法的方式来访问静态变量
    static String company; //这里缺省权限修饰符,是为了演示在类外面演示“类名.静态变量”的方式访问
    private int id;
    private String name;

    {
        //两个构造器的公共代码可以提前到非静态代码块
        total++; 
        id = total; //这里使用total静态变量的值为id属性赋值
    }

    public Employee() {
    }

    public Employee(String name) {
        this.name = name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static int getTotal() {
        return total;
    }

    public static void setTotal(int total) {
        Employee.total = total;
    }

    @Override
    public String toString() {
        return "Employee{company = " + company + ",id = " + id + " ,name=" + name +"}";
    }
}
public class TestStaticVariable {
    public static void main(String[] args) {
        //静态变量total的默认值是0
        System.out.println("Employee.total = " + Employee.getTotal());

        Employee c1 = new Employee("张三");
        Employee c2 = new Employee();
        System.out.println(c1);//静态变量company的默认值是null
        System.out.println(c2);//静态变量company的默认值是null
        System.out.println("Employee.total = " + Employee.getTotal());//静态变量total值是2

        Employee.company = "1";
        System.out.println(c1);//静态变量company的值是1
        System.out.println(c2);//静态变量company的值是1

        //只要权限修饰符允许,虽然不推荐,但是也可以通过“对象.静态变量”的形式来访问
        c1.company = "超级";

        System.out.println(c1);//静态变量company的值是超级
        System.out.println(c2);//静态变量company的值是超级
    }
}
3、静态变量内存分析
4、静态类变量和非静态实例变量、局部变量
  • 静态类变量(简称静态变量):存储在方法区,有默认值,所有对象共享,生命周期和类相同,还可以有权限修饰符、final等其他修饰符

  • 非静态实例变量(简称实例变量):存储在中,有默认值,每一个对象独立,生命周期每一个对象也独立,还可以有权限修饰符、final等其他修饰符

  • 局部变量:存储在中,没有默认值,每一次方法调用都是独立的,有作用域,只能有final修饰,没有其他修饰符

静态方法

有static修饰的成员方法就是静态方法。

【修饰符】 class 类{
    【其他修饰符】 static 返回值类型 方法名(形参列表){
        方法体
    }
}

2、静态方法的特点
  • 静态方法在本类的任意方法、代码块、构造器中都可以直接被调用。

  • 只要权限修饰符允许,静态方法在其他类中可以通过“类名.静态方法“的方式调用。也可以通过”对象.静态方法“的方式调用(但是更推荐使用类名.静态方法的方式)。

  • 静态方法可以被子类继承,但不能被子类重写。

  • 静态方法的调用都只看编译时类型。



public class Father {
    public static void method(){
        System.out.println("Father.method");
    }

    public static void fun(){
        System.out.println("Father.fun");
    }
}

public class Son extends Father{
//    @Override //尝试重写静态方法,加上@Override编译报错,去掉Override不报错,但是也不是重写
    public static void fun(){
        System.out.println("Son.fun");
    }
}

public class TestStaticMethod {
    public static void main(String[] args) {
        Father.method();
        Son.method();//继承静态方法

        Father f = new Son();
        f.method();//执行Father类中的method
    }
}

静态代码块

如果想要为静态变量初始化,可以直接在静态变量的声明后面直接赋值,也可以使用静态代码块。

1、语法格式

在代码块的前面加static,就是静态代码块。

 【修饰符】 class 类{
    static{
        静态代码块
    }
}

2、静态代码块的特点

每一个类的静态代码块只会执行一次。

静态代码块的执行优先于非静态代码块和构造器。

public class Chinese {
//    private static String country = "中国";

    private static String country;
    private String name;

    {
        System.out.println("非静态代码块,country = " + country);
    }

    static {
        country = "中国";
        System.out.println("静态代码块");
    }

    public Chinese(String name) {
        this.name = name;
    }
}

 public class TestStaticBlock {
    public static void main(String[] args) {
        Chinese c1 = new Chinese("张三");
        Chinese c2 = new Chinese("李四");
    }
}

3、静态代码块和非静态代码块

静态代码块在类初始化时执行,只执行一次

非静态代码块在实例初始化时执行,每次new对象都会执行

类初始化

(1)类的初始化就是为静态变量初始化。实际上,类初始化的过程时在调用一个<clinit>()方法,而这个方法是编译器自动生成的。编译器会将如下两部分的所有代码,按顺序合并到类初始化<clinit>()方法体中。

  • 静态类成员变量的显式赋值语句

  • 静态代码块中的语句

(2)每个类初始化只会进行一次,如果子类初始化时,发现父类没有初始化,那么会先初始化父类。

(3)类的初始化一定优先于实例初始化。

1、类初始化代码只执行一次

public class Fu{
    static{
        System.out.println("Fu静态代码块1,a = " + Fu.a);
    }
    private static int a = 1;
    static{
        System.out.println("Fu静态代码块2,a = " + a);
    }
    
    public static void method(){
        System.out.println("Fu.method");
    }

}

 public class TestClassInit {
    public static void main(String[] args) {
        Fu.method();
    }
}

2、父类优先于子类初始化

public class Zi extends Fu{
    static{
        System.out.println("Zi静态代码块");
    }
}

 public class TestZiInit {
    public static void main(String[] args) {
        Zi z = new Zi();
    }
}

3、类初始化优先于实例初始化
public class Fu{
    static{
        System.out.println("Fu静态代码块1,a = " + Fu.a);
    }
    private static int a = 1;
    static{
        System.out.println("Fu静态代码块2,a = " + a);
    }

    {
        System.out.println("Fu非静态代码块");
    }
    public Fu(){
        System.out.println("Fu构造器");
    }

    public static void method(){
        System.out.println("Fu.method");
    }
}
public class Zi extends Fu{
    static{
        System.out.println("Zi静态代码块");
    }
    {
        System.out.println("Zi非静态代码块");
    }
    public Zi(){
        System.out.println("Zi构造器");
    }
}
public class TestZiInit {
    public static void main(String[] args) {
        Zi z1 = new Zi();
        Zi z2 = new Zi();
    }
}

静态和非静态的区别

本类中的访问限制区别

静态的类变量和静态的方法可以在本类的任意方法、代码块、构造器中直接访问。

非静态的实例变量和非静态的方法==只能==在本类的非静态的方法、非静态代码块、构造器中直接访问。

  • 静态直接访问静态,可以

  • 非静态直接访问非静态,可以

  • 非静态直接访问静态,可以

  • 静态直接访问非静态,不可以

2、在其他类的访问方式区别

静态的类变量和静态的方法可以通过“类名.”的方式直接访问;也可以通过“对象."的方式访问。(但是更推荐使用类名的方式)

非静态的实例变量和非静态的方法==只能==通过“对象."方式访问。

3、this和super的使用

静态的方法和静态的代码块中,==不允许==出现this和super关键字,如果有重名问题,使用“类名.”进行区别。

非静态的方法和非静态的代码块中,可以使用this和super关键字。

静态导入

如果大量使用另一个类的静态成员,可以使用静态导入,简化代码。

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

import static java.lang.Math.*;

public class TestStaticImport {
    public static void main(String[] args) {
        //使用Math类的静态成员
        System.out.println(Math.PI);
        System.out.println(Math.sqrt(9));
        System.out.println(Math.random());

        System.out.println("----------------------------");
        System.out.println(PI);
        System.out.println(sqrt(9));
        System.out.println(random());
    }
}

枚举

枚举类型本质上也是一种类,只不过是这个类的对象是固定的几个,而不能随意让用户创建。

某些类型的对象是有限的几个,这样的例子举不胜举:

  • 星期:Monday(星期一)......Sunday(星期天)

  • 性别:Man(男)、Woman(女)

  • 月份:January(1月)......December(12月)

  • 季节:Spring(春节)......Winter(冬天)

  • 支付方式:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)

  • 员工工作状态:Busy(忙)、Free(闲)、Vocation(休假)

  • 订单状态:Nonpayment(未付款)、Paid(已付款)、Fulfilled(已配货)、Delivered(已发货)、Checked(已确认收货)、Return(退货)、Exchange(换货)、Cancel(取消)

在JDK1.5之前,需要程序员自己通过特殊的方式来定义枚举类型。

在JDK1.5之后,Java支持enum关键字来快速的定义枚举类型。

JDK1.5之前

在JDK1.5之前如何声明枚举类呢?

  • 构造器加private私有化

  • 本类内部创建一组常量对象,并添加public static修饰符,对外暴露这些常量对象

/**
 *枚举什么时枚举??
 * 枚举就是一一罗列出来的类
 * 只不过这个类的对象是固定的几个  ,不能随意让用户创建
 * 在JDK1.5之前如何声明枚举类呢?
 *
 * * 构造器加private私有化
 * * 本类内部创建一组常量对象,并添加public static修饰符,对外暴露这些常量对象
 *
 *
 */

public class Season {
//    快捷键  ctrl+shift+U
    public static  final  Season SPRING = new Season();
    public static final Season SUMMER  = new Season();
    public static final Season AUTUMN = new Season();
    public static final Season WINTER =new Season();
    private Season(){
        System.out.println("空参构造");

    }

    @Override
    public String toString() {
       if(this == SPRING){
           return "春";
       }else if (this == SUMMER){
           return "夏天";
        }else if(this == AUTUMN){
           return "秋天";
       }else if(this == WINTER){
           return "冬天";
       }else{
           return "错误";
       }
    }
}

public class TestSeason {
    public static void main(String[] args) {
        Season s1 = Season.SPRING;
        System.out.println(s1);
        Season s2 = Season.AUTUMN;
        Season s3 = Season.WINTER;
        Season s4 =Season.SUMMER;
        System.out.println(s2+","+s3+","+s4+"。");
    }
}
enum关键字声明枚举

        

【修饰符】 enum 枚举类名{
    常量对象列表
}

【修饰符】 enum 枚举类名{
    常量对象列表;
    
    其他成员列表;
}

public enum Week {
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
public class TestEnum {
	public static void main(String[] args) {
		Season spring = Season.SPRING;
		System.out.println(spring);
	}
}

枚举类的要求和特点

枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写。

如果常量对象列表后面没有其他代码,那么“;”可以省略,否则不可以省略“;”。

public enum Week {
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
//;分号可以省略
}

编译器给枚举类默认提供的是private的无参构造,如果枚举类需要的是无参构造,就不需要声明,写常量对象列表时也不用加参数,

//    private Week(){
//    }
//    默认无参构造

如果枚举类需要的是有参构造,需要手动定义,有参构造的private可以省略,调用有参构造的方法就是在常量对象名后面加(实参列表)就可以。

public enum Week {
    MONDAY("你好啊"),TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
//    private Week(){
//    }
//    默认无参构造
    private final String description;
    private Week(){
        description="";
    }
//    有参构造
    private Week(String description){
        this.description=description;
    }

}

枚举类默认继承的是java.lang.Enum类,因此不能再继承其他的类型。

JDK1.5之后switch,提供支持枚举类型,case后面可以写枚举常量名。

public enum Week {
    MONDAY("你好啊"),TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
//    private Week(){
//    }
//    默认无参构造
    private final String description;
    private Week(){
        description="";
    }
//    有参构造
    private Week(String description){
        this.description=description;
    }
    public static String show (Week week){
        switch(week){
            case MONDAY:
                return "星期一";
            case WEDNESDAY:
                return "星期三";
            case THURSDAY:
                return "星期四";
            case TUESDAY:
                return "星期二";
            case FRIDAY:
                return "星期五";
            case SATURDAY:
                return "星期六";
            case SUNDAY:
                return "星期日";
            default:
                return "输入错误";
        }
    }

    public static void main(String[] args) {
        Week w1 = Week.MONDAY;
        System.out.println(Week.show(w1));
    }

}

 枚举类型如有其它属性,建议(不是必须)这些属性也声明为final的,因为常量对象在逻辑意义上应该不可变。

public enum Week {
    MONDAY("星期一1"),TUESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");

//    private Week(){
//    }
//    默认无参构造
    private final String description;
    private Week(){
        description="";
    }
//    有参构造
    private Week(String description){
        this.description=description;
    }
    public static String show (Week week){
        switch(week){
            case MONDAY:
                return "星期一";
            case WEDNESDAY:
                return "星期三";
            case THURSDAY:
                return "星期四";
            case TUESDAY:
                return "星期二";
            case FRIDAY:
                return "星期五";
            case SATURDAY:
                return "星期六";
            case SUNDAY:
                return "星期日";
            default:
                return "输入错误";
        }
    }


    public static void main(String[] args) {
        Week w1 = Week.MONDAY;
        System.out.println(w1);
        System.out.println(Week.show(w1));
        switch(w1){
            case MONDAY:
                System.out.println("怀念周末,困意很浓");
                break;
            case TUESDAY:
                System.out.println("进入学习状体");
                break;
            case WEDNESDAY:
                System.out.println("死撑");
                break;
            case THURSDAY:
                System.out.println("小放松");
                break;
            case FRIDAY:
                System.out.println("又信心慢慢");
                break;
            case SATURDAY:
                System.out.println("无心学习,开始期待周末");
                break;
            case SUNDAY:
                System.out.println("一睡觉到下午");
                break;
            default:
                break;
        }
    }

    @Override
    public String toString() {
        return description;
    }
}

3、枚举类型常用方法

1.String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
2.String name():返回的是常量名(对象名)
3.int ordinal():返回常量的次序号,默认从0 开始
4.枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
5.枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象

public class TestEnumMethod {
    public static void main(String[] args) {
        Week[] values = Week.values();
        for (int i = 0; i < values.length; i++) {
            System.out.println((values[i].ordinal()+1) + "->" + values[i].name());
        }
        System.out.println("------------------------");

        Scanner input = new Scanner(System.in);
        System.out.print("请输入星期值:");
        int weekValue = input.nextInt();
        Week week = values[weekValue-1];
        System.out.println(week);

        System.out.print("请输入星期名:");
        String weekName = input.next();
        week = Week.valueOf(weekName);
        System.out.println(week);

        input.close();
    }
}

包装类

Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而当要使用只针对对象设计的API或新特性(例如泛型),那么基本数据类型的数据就需要用包装类来包装。

装箱与拆箱

装箱:把基本数据类型转为包装类对象。

转为包装类的对象,是为了使用专门为对象设计的API和特性.

拆箱:把包装类对象拆为基本数据类型。

转为基本数据类型,一般是因为需要运算,Java中的大多数运算符是为基本数据类型设计的。比较、算术等

基本数值---->包装对象

Integer a1 = new Integer(1);使用构造函数、

Integer a2 = Integer.valueOf(4);//使用包装类的valueOf方法

 包装对象---->基本数值

Integer obj = new Interger( 4);

int num1= obj.intvalue();

 JDK1.5之后,可以自动装箱与拆箱。

注意:只能与自己对应的类型之间才能实现自动装箱与拆箱 .

Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
//加法运算完成后,再次装箱,把基本数值转成对象。

 Integer i = 1;
Double d = 1;//错误的,1是int类型

包装类的一些API

基本数据类型和字符串之间的转换

(1)把基本数据类型转为字符串

int a = 10;
//String str = a;//错误的
//方式一:
String str = a + "";
//方式二:
String str = String.valueOf(a);

(2)把字符串转为基本数据类型

String转换成对应的基本类型 ,除了Character类之外,其他所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型,例如:

  • public static int parseInt(String s):将字符串参数转换为对应的int基本类型。

  • public static long parseLong(String s):将字符串参数转换为对应的long基本类型。

  • public static double parseDouble(String s):将字符串参数转换为对应的double基本类型。

或把字符串转为包装类,然后可以自动拆箱为基本数据类型

  • public static Integer valueOf(String s):将字符串参数转换为对应的Integer包装类,然后可以自动拆箱为int基本类型

  • public static Long valueOf(String s):将字符串参数转换为对应的Long包装类,然后可以自动拆箱为long基本类型

  • public static Double valueOf(String s):将字符串参数转换为对应的Double包装类,然后可以自动拆箱为double基本类型

 注意:如果字符串参数的内容无法正确转换为对应的基本类型,则会抛出java.lang.NumberFormatException异常。

int a = Integer.parseInt("整数的字符串");
double d = Double.parseDouble("小数的字符串");
boolean b = Boolean.parseBoolean("true或false");

int a = Integer.valueOf("整数的字符串");
double d = Double.valueOf("小数的字符串");
boolean b = Boolean.valueOf("true或false");

、数据类型的最大最小值
Integer.MAX_VALUE和Integer.MIN_VALUE
Long.MAX_VALUE和Long.MIN_VALUE
Double.MAX_VALUE和Double.MIN_VALUE
3、字符转大小写

 Character.toUpperCase('x');
Character.toLowerCase('X');

4、整数转进制

Integer.toBinaryString(int i)
Integer.toHexString(int i)
Integer.toOctalString(int i) 

、比较的方法

Double.compare(double d1, double d2)
Integer.compare(int x, int y)

包装类对象的特点

包装类缓存对象
包装类 缓存对象
Byte -128~127
Short -128~127
Integer -128~127
Long -128~127
Float 没有
Double 没有
Character 0~127
Boolean true和false
类型转换问题
Integer i = 1000;
double j = 1000;
System.out.println(i==j);//true  会先将i自动拆箱为int,然后根据基本数据类型“自动类型转换”规则,转为double比较

Integer i = 1000;
int j = 1000;
System.out.println(i==j);//true 会自动拆箱,按照基本数据类型进行比较

、包装类对象不可变
public class TestExam {
	public static void main(String[] args) {
		int i = 1;
		Integer j = new Integer(2);
		Circle c = new Circle();
		change(i,j,c);
		System.out.println("i = " + i);//1
		System.out.println("j = " + j);//2
		System.out.println("c.radius = " + c.radius);//10.0
	}
	
	/*
	 * 方法的参数传递机制:
	 * (1)基本数据类型:形参的修改完全不影响实参
	 * (2)引用数据类型:通过形参修改对象的属性值,会影响实参的属性值
	 * 这类Integer等包装类对象是“不可变”对象,即一旦修改,就是新对象,和实参就无关了
	 */
	public static void change(int a ,Integer b,Circle c ){
		a += 10;
//		b += 10;//等价于  b = new Integer(b+10);
		c.radius += 10;
		/*c = new Circle();
		c.radius+=10;*/
	}
}
class Circle{
	double radius;
}

    /*
     * 方法的参数传递机制:
     * (1)基本数据类型:形参的修改完全不影响实参
     * (2)引用数据类型:通过形参修改对象的属性值,会影响实参的属性值
     * 这类Integer等包装类对象是“不可变”对象,即一旦修改,就是新对象,和实参就无关了
     */

抽象类

抽象:即不具体、或无法具体

例如:当我们声明一个几何图形类:圆、矩形、三角形类等,发现这些类都有共同特征:求面积、求周长、获取图形详细信息。那么这些共同特征应该抽取到一个公共父类中。但是这些方法在父类中又无法给出具体的实现,而是应该交给子类各自具体实现。那么父类在声明这些方法时,就只有方法签名,没有方法体,我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类必须是抽象类

语法格式

  • 抽象方法:被abstract修饰没有方法体的方法。

  • 抽象类:被abstract修饰的类。

抽象类的语法格式

【权限修饰符】 abstract class 类名{
    
}
【权限修饰符】 abstract class 类名 extends 父类{
    
}

抽象方法的语法格式

【其他修饰符】 abstract 返回值类型 方法名(【形参列表】); 

注意:抽象方法没有方法体

public abstract class Animal {
    public abstract void eat();
}
public class Cat extends Animal {
    public void run (){
      	System.out.println("小猫吃鱼和猫粮"); 	 
    }
}
public class CatTest {
 	 public static void main(String[] args) {
        // 创建子类对象
        Cat c = new Cat(); 
       
        // 调用eat方法
        c.eat();
  	}
}

此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法

注意事项

关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

    理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  2. 抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。

    理解:子类的构造方法中,有默认的super()或手动的super(实参列表),需要访问父类构造方法。

  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。

    理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

修饰符一起使用问题?

        

外部类 成员变量 代码块 构造器 方法 局部变量 内部类(后面讲)
public × ×
protected × × ×
缺省 × ×
private × × ×
static × × ×
final × ×
abstract × × × ×
native × × × × × ×


不能和abstract一起使用的修饰符?

(1)abstract和final不能一起修饰方法和类

(2)abstract和static不能一起修饰方法

(3)abstract和native不能一起修饰方法

(4)abstract和private不能一起修饰

static和final一起使用

(1)修饰方法:可以,因为都不能被重写

(2)修饰成员变量:可以,表示静态常量

(3)修饰局部变量:不可以,static不能修饰局部变量

(4)修饰代码块:不可以,final不能修改代码块

(5)修饰内部类:可以一起修饰成员内部类,不能一起修饰局部内部类


网站公告

今日签到

点亮在社区的每一天
去签到