JAVA之从入门到放弃(三)

访问修饰符 (访问控制)

作用:控制当前代码的可见范围 目的:保护程序的合法性,安全性,健壮性
属性的封装:属性私有化,方法公开化

public(公开的):任意位置都可以访问,权限最大
protected(保护的):一般存在父级代码中,当前类/同包类/子类 可见
默认的:默认访问修饰符是不建议的 当前类/同包类 可见
private(私有的):权限最小 当前类 可见

final

final代表的是最终的意思,可以修饰类、属性、方法

  • 修饰属性:final修饰符变量要么在声明时初始化,要么在构造方法中初始化
  • 修饰方法:final修饰的方法不可以被重写,所以存在于父级代码中
  • 修饰类:final修饰的类不可以被继承
//final测试演示类
public class FinalDemo {
    private final int a; //final修饰符变量要么在声明时初始化
    FinalDemo() {
        a = 10; //final修饰符变量要么在构造方法中初始化
    }

    void show() {
//        a = 10; //final修饰符变量不能再普通方法中初始化
    }
}

final class Aoo { //final修饰的类不可以被继承
    public final void test() { //final修饰的方法不可以被重写

    }
}

class Boo/* extends Aoo*/ {
//    public void test() {   //不可以重写
//
//    }
}
static (静态变量)
静态资源:

如:
每个学生的杯子属于对象吗?属于,属于个人的
饮水机属于对象吗?不属于,但可以被对象共享。----->静态资源

  • 实例变量:属于对象的!特点:有多少个对象就有多少份,在堆中
    • 实例变量的访问:通过对象名打点的形式访问
  • 静态变量:属于类的!特点:有且只有一份,被所有对象共享,在方法区中存储
    • 静态变量的访问:通过类名打点的形式访问
  • 静态变量适用性:当一份资源需要被多个对象共享时可以做成静态资源
方法区特点:一个类应该有一份.class字节码文件,当类被首次使用时,该类的.class 字节码文件会被加载到方法区中,加载且只加载一次

JVM分配空间:栈区,堆区,方法区
栈区:放局部变量的区域
堆区:放对象的区域
方法区:用来加载.class字节码文件(类中的静态变量,类中的方法(构造方法/静态方法/普通方法))

class Coo {
    public int a;//实例变量:属于对象的,有多个对象有多少份
    public static int b;//静态变量:属于类的,只有一份被所有对象共享
    Coo() {
        a++;
        b++;
    }
    void show() {//普通方法
        this.a = 0;//访问类实例成员默认有个this的写法
        Coo.b = 0;//访问类静态成员默认有个类名点的写法
        System.out.println("实例变量a的值:" + a + ",静态变量b的值:" + b);
    }
    static void show2() {//静态方法中:无法使用this
//        this.a = 1;  普通实例成员不可直接在static修饰的方法中调用
//           this.show();普通方法不可直接在static修饰的方法中调用
        Coo.b = 1;//静态方法可直接访问静态的内容.
    }
}
static (静态方法)

用static修饰的方法称之为静态方法

  • 静态方法属于类,通过类名打点调用
  • 静态方法存储在方法区中
  • 静态方法时没有隐式this传递的,所以静态方法是无法访问类中实例成员(普通实例变量,普通方法)
  • 静态方法的适用性:静态方法一般存在于工具类中,对于外部来讲调用方便,只需要类名点的形式就可以调用该方法
class Coo {
    private int a; //实例变量:属于对象的,有多少个对象有多少份
    public static int b; //静态变量:属于类的,有且只有一份被所有对象共享
    Coo() {
        a ++;
        b ++;
    }

    void show() {   //普通方法
        this.a = 0; //访问类实例成员默认有个this
        Coo.b = 0;  //访问静态成员默认有个类名点的写法
        System.out.println("实例变量a的值:" + a + "静态变量b的值:" + b);
    }
    static void show2() { // 静态方法中:无法使用this
//        a = 0;        普通实例成员不可以在static修饰的方法中调用
//        this.show();  普通方法不可以在static修饰的方法中调用
        Coo.b = 2;     //静态方法可以直接访问类的静态内容
    }
}
static (静态代码块)
  • 用static修饰的代码块称之为静态代码块
  • 静态代码块属于类,当类被首次加载时,会自动调用静态代码块且只调用一次
  • 静态代码块适用性:当成员都是静态成员时,也无需外部创建对象,类中静态成员初始化赋值的功能,可以交给静态代码块来完成
/*测试静态代码块的类*/
public class StaticDemo2 {
    public static void main(String[] args) {
//        Doo doo1 = new Doo();
//        Doo doo2 = new Doo();
        Doo doo3 = new Doo();
//        Doo.a = 2; //访问类中的静态成员 也叫使用类,如果是首次使用则会加载
    }
}

class Doo {
    public static int a = 2;
    Doo() { //创建多少个对象 则执行多少次   构造方法的作用:创建对象时可以为对象初始化数据
        System.out.println("Doo类的构造方法执行了");
    }
    static {    //静态代码块:类被首次加载时执行,且只加载一次  静态代码块的作用:一般用于为静态成员初始化使用的语法
        System.out.println("Doo类被加载了。。我执行了。。");
    }
}
常量

用static final修饰的属性则是常量,常量结合static和final的特性
特性:常量可以通过类名打点形式访问,不能二次修改且声明时需要初始化
常量命名:要求纯大写,多个单词之间用下划线隔开
常量的适用性:当有一份数据,确定后几乎不会发生改变的,也不会频繁修改得,那么可以作为常量来表示,常量一般也可以用于表示一些固定状态的使用

/*常量的使用演示类*/
public class StaticFinalDemo {
    public static void main(String[] args) {
//        System.out.println(Eoo.a);
//        Eoo e = new Eoo();
//        System.out.println(e.b);

        /*1.先将Eoo类字节码文件加载到方法区
        * 2.输出静态变量a的值*/
        System.out.println(Eoo.a);

       /*在编译期间使用常量,本质上就是将常量的值进行访问(不会执行static代码块)*/
        System.out.println(Eoo.C);
    }
}

class Eoo {
    public static int a;            //静态变量
    public final int b = 1;         //final修饰的变量
    public static final int C = 100;//常量
    static {
        System.out.println("静态代码块执行了、、、、");
    }
}
抽象方法(半成品)
  • 用abstract修饰的方法称之为抽象方法
  • 抽象方法需要存在于抽象类
  • 抽象方法不能有方法体
  • 抽象方法必须要子类重写
抽象类
  • 用abstract修饰的类称之为抽象类
  • 抽象类不能被实例化对象
  • 抽象类只是能在普通类的基础上可以放抽象内容而已
  • 抽象类一定要有子类实现的,否则抽象类没有意义

抽象方法的意义:
1)遵循面向对象设计原则,如果父类中提供的方法子类都不能用是不是需要重写?
如果做成普通方法,子类是不是可以重写 也可以不重写?
目的:为了约束子类必须重写,不重写代码报错
2)子类都重写了,父类的抽象方法还有存在的意义吗?
目的:父类中存在的抽象方法的意义是为了向上造型,调用父类执行子类

内部类 (应用率不高)

内部类:类中套个类,类结构中的类称之为内部类

  • 内部类不具备可见性
  • 内部类共享外部类成员,可以直接访问。但如果外部类成员命名与内部类成员命名冲突时,那么我们可以明确写外部类名.this.xx即可
class Aoo { //外部类
      class Boo { //内部类
      }
}
匿名内部类 (应用率高)

匿名内部类:没有名字的内部类称之为匿名内部类
适用性:当一个子类仅仅只是为了实现重写父类中的某个功能时,而其他地方根本不用该子类,那么我们可以使用匿名内部类的方式,目的:让面相实现开发,而不关心语法,更关心的是逻辑如何实现

  • 匿名内部类的使用:只会存在于只是重写父类方法的情况才会使用
  • 匿名内部类访问外部类成员:对于
        //1.创建一个匿名内部类,花括号就是匿名子类的类体
        //2.运行时创建的子类对象赋值给sub
        //3.通过sub调用重写的show方法
        SupperDemo sub = new SupperDemo() {
            @Override
            void show() {
//                sub.a = 20; // 匿名内部类访问外部类成员 会自动修饰为final, a不可二次修改
                System.out.println(a); //可以访问
                System.out.println("匿名内部类重写了父类中的show方法");
            }
        };
        sub.show();

问:内部类有没有独立的.class字节码文件?
答:无论是成员内部类还是匿名内部类都有.class字节码文件


数组扩容

Arrays.copy

        int[] array = {}; //为array数组创建了一个数组对象, 数组长度为0
        int a = 100;
        //copyOf: 1.要扩容的数组对象 2.基于原数组长度的基础上 + 或 - 要扩容或缩容的容量
        array = Arrays.copyOf(array, array.length + 1);
        System.out.println("扩容后" + array.length);
        array[array.length - 1] = a;
        System.out.println("存数后" + Arrays.toString(array));

System.arrayCopy

        int[] a = {50, 60, 70, 80};
        int[] b = {0, 0, 0, 0};
        /*arrayCopy的5个参数
        * 1.要拷贝的原数组
        * 2.从原数组哪个下标开始拷贝
        * 3.要拷贝到的目标数组
        * 4.从目标数组哪个下标开始装载
        * 5.拷贝的数量, 目标数组长度 - 目标数组装载的下标
        (注意:拷贝的数量不能超过目标数组容纳的范围)*/
        System.arraycopy(a, 1, b, 1, a.length - 1);
接口

定义:接口是一组行为的规范,接口并不关心多个类之间是否是一种的关系,只关心这些类的行为是否一样,一个类可以实现多个接口,一般一个接口只代表一个行为,不要做大而全的接口,要做小而精的接口

  • 接口是一种数据类型,是引用类型,同样也有.class字节码文件
  • 接口使用interface关键字来定义
  • 接口中只能放常量和和抽象方法
  • 实现类必须重写接口中的所有方法 使用implement戳上接口名来实现
  • 实现类又要继承类 又要实现接口的方法 那么先继承后实现接口方法
  • 实现类可以实现多个接口,实现时接口名之间用逗号隔开
  • 接口之间是可以继承的
抽象类和接口的区别
  • 语法区别:
    • 抽象类可以有构造方法 | 接口没有
    • 抽象类可以有普通变量、方法/抽象方法 | 接口只能放常量,抽象方法1.8支持静态方法
    • 抽象类成员可选择不同访问修饰符 | 接口默认都是public
    • 一个类只能继承类 | 接口可以继承多个接口
  • 设计使用区别
    • 继承:多个类之间存在共性的属性和行为时,且这些类在概念上是一种的关系,可以用继承来复用优化代码
      • 继承好处:复用代码(属性),可以向上造型,调父执行子
      • 继承缺点:耦合度高,牵一发而动全身
    • 接口:多个类之间存在共有行为时,不管这些类概念上是否是一种的关系,可以用接口来代表这些类的行为
      • 接口好处:代表行为,可以向上造型,调用父执行,接口是可以多实现
      • 高内聚:一个类或一个方法尽可能只干相关的事情 低耦合:类与类之间的关系尽量松散
多态

在程序中多态指的是,一个父类下的行为子类有不同的实现

向上造型:引用类型中的自动类型转换

能够向上造型的语法:实现继承关系 声明父 new子 | 实现关系 声明接口 new 实现类

向下转型:引用类型中的强制类型转换

引用类型中能否强制转换成功,具体参考以下两个条件

  • 条件1:要强转引用类型变量中的对象,就是要转换的这个类型
  • 条件2:要强转引用类型变量中的对象,实现了要转换的这个接口
    强转时建议用instanceof判断是否强转成功

你可能感兴趣的:(JAVA之从入门到放弃(三))