JavaSe第三天笔记小记

JavaSE第三天学习小记

1、java数组

与c++中的数组概念一致,把不同的只是语法

public class Hello {
    public static void main(String[] args) {
        /*效果相同
        int[] arr;  // 首选
        int arr[];  // 可用,但java中不建议用
         */
        int[] array1 = new int[5];      // 开辟五个存放int类型的数组
        int[] array2 = {1, 2, 3};       // 开辟分别存放1,2,3的数组 
        
        System.out.println("获取数组大小:" + array1.length);
    }
}

基本特点:

  • 长度确定,一旦被创建,大小不可改变
  • 存放元素必须是同一类型
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型
  • 数组变量属于引用类型,数组也可以看作是对象,数组中的每个元素相当于该对象的成员变量
  • 数组本身就是对象,java对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组本身都是在堆中的

三种初始化方式

1、静态初始化

int[] arr = {1,2,3};
Man[] mans = {new Man(1), new Man(2)};

2、动态初始化

int[] arr = new int[2];
arr[0] = 1;
arr[1] = 2;

3、数组的默认初始化

  • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

2、内存分析


3、Arrays类

java中的一个工具类,包含在java.util.Arrays包中

  • 数组本身没有方法供我们调用,所以API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作
  • 查看JDK帮助文档
  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象调用(是“不用”而不是“不能“)

常用方法:

  • 给数组赋值:通过fill方法
  • 对数组排序:通过sort方法,默认是从小到大排序
  • 比较数组:通过equals方法比较数组中元素值是否相等
  • 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作

4、冒泡排序

动图演示:

import java.util.Arrays;

public class Hello {
    public static void main(String[] args) {
        int[] arr = {21, 26, 12, 45, 23, 9, 12, 3, 3, 7};

        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int[] a) {
        // 冒泡排序算法实现
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j + 1] < a[j]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }
            }
        }
    }

}

结果:[3, 3, 7, 9, 12, 12, 21, 23, 26, 45]

5、面向对象

java中的面向对象思想与c++大体一致

  • 以类的方式组织代码,以对象的方式组织(封装)数据

5.1 构造器

即构造方法(c++里面的构造函数)

  • 必须和类的名字相同
  • 不能有返回类型,也不能写void
  • 使用new关键字创建对象的本质是在调用构造器
  • 一旦定义了有参构造,就没有默认的隐式无参构造函数,因此需要显式定义

5.2 访问权限

修饰符 描述 大白话
private 私有的,被private修饰的类、方法、属性、只能被本类的对象所访问 我什么都不跟别人分享。只有自己知道
default 默认的,在这种模式下,只能在同一个包内访问 我的东西可以和跟我一块住的那个人分享
protected 受保护的,被protected修饰的类、方法、属性、只能被本类、本包、不同包的子类所访问 我的东西我可以和跟我一块住的那个人分享。另外也可以跟不在家的儿子分享消息,打电话
public 公共的,被public修饰的类、方法、属性、可以跨类和跨包访问 我的东西大家任何人都可以分享

5.3 封装

  • 程序设计追求“高内聚,低耦合”
  • 数据的隐藏,通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问
  • 属性私有,get/set

5.4 继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
  • extends的意思是扩展,子类是父类的扩展
  • java中只有单继承,没有多继承
class People {
    String name;
    int age;
}

public class Student extends People{
    // 继承了父类,具有父类的属性
}

object类

  • java中所有的类,都默认直接或者间接继承Object

super

  • super调用父类的构造方法,必须在构造方法的第一行
  • super必须只能出现在子类的方法或者构造方法中
  • super和this不能同时调用构造方法
  • 只能在继承条件下才可以使用

this

  • 与super相比代表的对象不同:本身调用者这个对象
  • 没有继承也可以使用
this();		// 调用本类的构造
super();	// 调用父类的构造

5.5 重写与多态

重写:子类的方法与父类的方法必须相同,但是方法体不同

为什么需要重写:

  1. 父类的功能子类不一定需要或者不一定满足

重写的条件:

  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符:范围可以扩大但是不能缩小
  • 抛出的异常:范围可以被缩小但是不能扩大

多态:即同一方法可以根据发送对象的不同而采取多种不同行为

  • 一个对象的实际类型是确定的,但是指向这个对象的引用的类型却有很多
  • instanceof

存在的条件:

  1. 有继承关系
  2. 子类重写父类方法
  3. 父类引用指向子类对象

注意事项:

  • 多态是指方法的多态,属性没有多态
  • 父类和子类,有联系
  • 继承关系,方法需要重写,父类引用指向子类对象

静态方法的调用(不叫重写)

class A{
    public static void test(){
        System.out.println("A==>test()");
    }
}

public class B extends A{
    public static void test(){
        System.out.println("B==>test()");
    }
    
    public static void main(String[] args) {
        // 构造一个A类的对象
        A a1 = new A();
        a1.test();

        // 父类引用指向了子类
        A a2 = new B();
        a2.test();
    }
}

运行结果:

A==>test()
A==>test()

分析:静态方法的调用只和左边,即定义的数据类型有关

非静态方法的重写与调用

class A{
    public void test(){
        System.out.println("A==>test()");
    }
}

public class B extends A{
    // 子类重写了父类的方法
    public void test(){
        System.out.println("B==>test()");
    }

    public static void main(String[] args) {
        // 构造一个A类的对象
        A a1 = new A();
        a1.test();

        // A类型的变量实际接受B类型的对象
        A a2 = new B();
        a2.test();
    }
}

运行结果:

A==>test()
B==>test()

分析:非静态方法的调用和左边和右边都有关

  • 对象能否执行方法?得看指向这个对象的引用类中有没有这个方法,即父类指向子类,不能调用子类独有的方法
  • 对象执行什么方法?得看右边对象实际的类型来决定

5.6

class A{
}

public class B extends A{
    public static void main(String[] args) {
        B bb = new B();

        System.out.println(bb instanceof A);
    }
}

运行结果:

true


6、static

“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

用途:方便在没有创建对象的情况下来进行调用(方法/变量)。

  1. static方法

static方法一般称作静态方法,因为不依赖任何对象,所以不存在this。

在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。

  1. static变量

​ static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

  static成员变量的初始化顺序按照定义的顺序进行初始化。

  1. static代码块

static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次

因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。

注意

与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域

在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字

在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是**不允许用来修饰局部变量****


7、抽象类

// 抽象类, 抽象的抽象
public abstract class Action{
    // 制定约束,让别人来实现
    // 只有方法定义,没有方法的具体实现
    public abstract void doSomething();
}
  1. 抽象类不能创建对象,即不能new,只能靠子类去实现,而它本身只是制定了约束
  2. 抽象类中可以写普通的方法
  3. 抽象方法必须在抽象类中,即如果一个类包含抽象方法,那么该类必须是抽象类。
  4. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  5. 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
  6. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

抽象类的构造函数

虽然抽象类不能被实例化,但可以有构造函数。由于抽象类的构造函数在实例化派生类之前发生,所以,可以在这个阶段初始化抽象类字段或执行其它与子类相关的代码。


8、接口

普通类:只有具体实现

抽象类:具体实现和规范(抽象方法)都有

接口:只有规范,专业的约束,约束和实现分离:面向接口编程

关键字:interface implements

  • 接口中的所有方法的定义都是抽象的,即public abstract,可省略,属性都为public static final
  • java不支持多继承,但是支持实现多接口,间接实现多继承
  • 接口没有构造方法
interface A {
    void say();
}

// 实现接口
public class Action implements A{

    @Override
    public void say() {
        System.out.println("Hello World!");
    }

    public static void main(String[] args) {
        new Action().say();
    }
}

运行结果:

Hello World!


9、内部类(奇葩!)

首先说明本质:无限套娃

9.1 成员内部类

public class Outer{
    int age = 11;

    public void out(){
        System.out.println("外部类的方法");
    }
	
    // 成员内部类
    public class Inner{
        public void in(){
            System.out.println("内部类的方法");
        }
    }


    public static void main(String[] args) {
        // 正常创建对象的形式
        Outer outer = new Outer();

        // 调用成员内部类的方法
        // 通过Outer的对象new一个Inner的对象,用Outer.Inner类型的引用接受
        Outer.Inner in = outer.new Inner();

        in.in();
    }
}

9.2 局部内部类

public class Outer{

    public void method(){
        // 局部内部类
        class Inner {
            public void in(){

            }
        }
    }

}

9.3 匿名内部类

interface User{
    void say();
}

public class Outer{
    public static void main(String[] args) {
        new User(){
            @Override
            public void say() {
                System.out.println("实现了接口的方法");
            }
        };
    }
}
posted @ 2020-07-21 21:23  lorz5  阅读(141)  评论(0编辑  收藏  举报