包(Package)

包是为了java程序编写时对类分类管理而创建的文件夹

格式:package 包名;(多级包用.隔开)
如:package JavaProject.first;
实际上是创建了JavaProject文件夹,并在文件夹下创建first文件夹

在编译带包的java文件时,可以手动创建包并将编译好的class文件放入包中,或者是通过命令“javac -d .文件名.java”在文件所在目录下自动创建包并完成编译,执行时需要带包执行,即“java JavaProject.first.文件名”

导包

使用不同包下的类时,需要使用类的全路径,为了简化带包的操作,java提供了导包的功能

格式:import 包名;
如:import java.util.Scanner;
即导入java/util文件夹下的Scanner文件夹内所有类

修饰符

权限修饰符

访问权限 子类 其他包 说明
public 对任何人都是可用的
protect × 继承的类可以访问以及和private一样的权限
default × × 包访问权限,即在整个包内均可被访问
private × × × 除类型创建者和类型的内部方法之外的任何人都不能访问的元素

状态修饰符

final

final(最终态):可以修饰成员方法,成员变量,类

  • 修饰方法:表明该方法是最终方法,不能被重写
  • 修饰变量:表明该变量时常量,不能再次被赋值
  • 修饰类:表明该类时最终类,不能被继承
  • 修饰局部变量:当变量是基本类型时,数据值不能改变,当变量时引用类型时,地址值不能改变,但数据值可以改变

static

static(静态):可以修饰成员方法和成员变量

static修饰的特点:

  • 被类的所有对象共享
  • 可以通过对象名和类名调用,推荐类名调用

static访问的特点:静态成员方法只能访问静态成员

集合基础

集合类可以提供一种存储空间可变的存储模型,存储的数据容量可以发生改变,较常用的有ArrayList

ArrayList

ArrayList< E>:位于util包下,实现可调整大小的数组,其中< E>是一种特殊的数据类型,泛型,可用引用数据类型替换

构造方法和添加方法

  • public ArrayList():创建一个空的集合对象
  • public boolean add(E e):将指定的元素追加到此集合的末尾
  • public void add(int index,E element):在此集合的指定位置插入指定的元素
创建ArrayList:
ArrayList<数据类型> 变量名=new ArrayList<数据类型>();
例如:ArrayList<String> array=new ArrayList<数据类型>();

常用方法

  • public boolean remove(Object o):删除指定的元素,返回删除是否成功
  • public E remove(int index):删除指定索引处的元素,返回被删除的元素
  • public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
  • public E get(int index):返回指定索引处的元素
  • public int size():返回集合中的元素的个数

String

string类在java.lang下,所以使用不需要导入包

字符串的特点:

  • 字符串不可变,值在创建后不能被更改
  • 虽然String值不可变,但是可以被共享
  • 字符串效果上相当于字符数组(char[]),但底层原理是字节数组(byte[])【JDK8及以前是字符数组,JDK9及以后是字节数组】

构造方法

方法名 说明
public String() 创建一个空白字符串对象,不含有任何内容
public String(char[] chs) 根据字符数组的内容,创建字符串对象
public String(byte[] bys) 根据字节数组的内容,创建字符串对象
String s=“abc”; 直接赋值的方式创建字符串对象,内容就是abc

特点

  • 通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同
  • 以“ ”方式给出的字符串,只要字符序列相同,无论在程序代码中出现几次,都只会创建一个String对象,并在字符串池中维护

比较

使用==比较时:

  • 基本类型:比较的是数据值是否相同
  • 引用类型:比较的是地址值是否相同

字符串本身是对象,比较内容是否相同,需要通过方法实现:equals()

public boolean equals(Object anObeject):将此字符串和指定对象进行比较,由于比较的是字符串对象,所以参数直接传递一个字符串

常用方法

  1. public char charAt(int index):返回字符串指定索引处的char值
  2. public int length():返回字符串长度

StringBuilder

StringBuilder是一个可变的字符串类,在拼接字符串时不会新建一个String对象,避免浪费空间

构造方法

  • public StringBuilder():创建一个空白可变字符串对象,不含有任何内容
  • public StringBuilder(String str):根据字符串的内容来创建可变字符串对象

常用方法

  • public StringBuilder append(任意类型):添加数据,并返回对象本身【可链式编程】
  • public StringBuilder reverse():返回相反的字符序列

和String的互相转换

  1. StringBuilder转换为String:public String toString()
  2. String转换为StringBuilder:public StringBuilder(String s)

接口(Interface)

一种公共的规范标准,java中的接口更多体现在堆行为的抽象

接口的定义:
public interface 接口名{}
类实现接口:
public class 类名 implements 接口名{}

特点:

  • 接口不能实例化——但可以通过实现类对象实例化
  • 接口的实现类要么重写接口中所有抽象方法,要么还是抽象类

方法的形参和返回值是接口名时,实际需要和返回的是该接口的实现类对象

接口的成员特点

  • 成员变量:

    只能是常量

    默认的修饰符为public static final

  • 构造方法:

    接口没有构造方法,因为接口主要对行为进行抽象,没有具体存在

    一个类如果没有父类,默认继承自Object类

  • 成员方法:

    只能是抽象方法

    默认修饰符为public abstract

类和接口的关系

类和接口可以是实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口,如:

public class 类名 extends 父类名 implement 接口1名,接口2名……{}

接口和接口可以是继承关系,可以单继承,也可以多继承

public interface 接口名 extends 接口1名,接口2名……{}

抽象类和接口的区别

  • 成员区别

    允许具有的成员
    抽象类 变量,常量,构造方法,抽象方法和非抽象方法
    接口 常量,抽象方法
  • 关系区别

    允许的关系
    类与类 继承,单继承
    类与接口 实现,可以单实现也可以多实现
    接口与接口 继承,单继承,多继承
  • 设计理念区别

    设计理念
    抽象类 对类抽象,包括属性,行为
    接口 对行为抽象,主要是行为

内部类

内部类:在一个类中定义一个类,如在类A中定义一个类B,则类B是类A的内部类

public class 类名{
修饰符 class 类名{

}
}

访问特点:

  • 内部类可以直接访问外部类的成员,包括私有
  • 外部类要访问内部类的成员,必须创建内部类的对象

按照内部类在类中定义的位置不同,可以分为两种:

  • 在类的成员位置:成员内部类
  • 在类的局部位置:局部内部类

成员内部类

非私有时可用以下格式在类外创建内部类对象:
外部类名.内部类名 对象名=外部类对象.内部类对象;
例如:
Outer.Inner oi=new Outer().new Inner();
当内部类私有时,则在外部类中写入公开方法,在类内创建内部类对象:
public class Outer{
private class Inner{
//此处省略内部类内容
}
public void InnerMethod(){
Inner i=new Inner();
//i即为创建的内部类对象
}
}

局部内部类

局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用,该类可以直接访问外部类的成员,也可以访问方法内的局部变量

public class Outer{
public void InnerMethod(){
private class Inner{
//此处省略内部类内容
}
Inner i=new Inner();
//i即为创建的内部类对象
}
}

如上,局部内部类Inner定义在方法InnerMethod中,使用内部类时需要直接在方法中创建内部类对象并调用内部类的方法,如果只创建内部类无法调用内部类的成员方法

匿名内部类

匿名内部类的前提:存在一个类或接口,可以是具体类或抽象类

格式:
new 类名或接口名(){
重写方法;
};
例如:
new Inner(){
public void show(){
//被重写的方法
}
};

匿名内部类本质上是一个继承了该类或实现了该接口的子类匿名对象,所以调用匿名内部类的方法时可以写作如下形式:

public class Outer{
public void InnerMethod(){
/*
new Inner(){
@Override
public void show()
{
System.out.println("匿名内部类");
}
};
以上只创建了匿名内部类,没有调用方法
*/
/*
new Inner(){
@Override
public void show()
{
System.out.println("匿名内部类");
}
}.show();
匿名内部类本质是一个匿名对象,所以直接可以通过对象调用方法
*/
Inner i=new Inner(){
@Override
public void show()
{
System.out.println("匿名内部类");
}
};
i.show();
//这个匿名的对象本身继承了该类或实现了该接口,故而可以将其赋值给其父类对象
}
}

使用匿名内部类可以简化操作,免去重新创建一个文件书写使用次数不多的类,而是将该类作为一个匿名内部类包含在同一个文件里,形如:

A a=new A();		//A为B的接口操作类
B b=new Bc(); //Bc为B子类
B b=new Bd(); //Bd为B子类
B b=new Be(); //Be为B子类
B b=new Bf(); //Bf为B子类
//此处省略多个B的子类
a.method(b); //method方法的参数为B类对象
//以上需要创建A接口类,B类,Bc类,Bd类,Be类,Bf类……等B的子类,但这些B的子类使用次数不多,甚至是一次性时,就会造成这些子类本身没什么用,而文件数量又过多

a.method(new B(){
@Override
//此处省略对B函数的重写
});
//使用匿名内部类作为参数时,也实现了子类对父类函数的重写,虽然代码量差不多,但是免去了创建无用的子类文件