参考教程

JDK8帮助文档

狂神说Java视频

static总结

静态变量与静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Student {
private static int age;//静态变量,在类中只有一个,对所有对象是共享的(多线程里常用)
private double score;//非静态变量

public void run(){//非静态方法
go();//非静态方法里可以直接访问静态方法
}

public static void go(){//静态方法
}

public static void main(String[] args) {
Student s1 = new Student();

System.out.println(Student.age);//静态变量推荐使用类名直接访问
//System.out.println(Student.score);报错:Non-static field 'score' cannot be referenced from a static context
System.out.println(s1.age);
System.out.println(s1.score);

s1.run();//非静态方法需要通过对象调用
s1.go();
Student.go();//静态方法直接用类名调用
go();//在本类里可以
//Student.run();报错:Non-static method 'run()' cannot be referenced from a static context
}
}

静态代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Person {

//No.2
{
//代码块(匿名代码块),程序在执行时并不能调用主动调用
//在创建对象的时候已经自动创建,且在构造器之前
//一般用来赋初始值
System.out.println("匿名代码块");
}

//No.1
static {
//静态代码块,类一加载就执行且永久执行一次
//可加载一些初始化的数据
System.out.println("静态代码块");
}

//No.3
public Person() {
System.out.println("构造方法");
}

public static void main(String[] args) {
Person person = new Person();
System.out.println("=================");
Person p2 = new Person();
}
}

输出结果:

1
2
3
4
5
6
静态代码块
匿名代码块
构造方法
=================
匿名代码块
构造方法

静态导入包

1
2
3
4
5
6
7
8
9
10
11
//import java.lang.Math.random;报错:Cannot resolve symbol 'random'
import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Test {
public static void main(String[] args) {
System.out.println(Math.random());
System.out.println(random());//静态导入包后可以直接使用方法
System.out.println(PI);
}
}

抽象类

abstract修饰符可以用来修饰方法——抽象方法,或者修饰类——抽象类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//抽象类,不能使用new来创建对象,是用来让子类继承的
public abstract class Action {
//抽象方法,只有方法声明没有方法实现,是用来让子类实现的
//抽象方法必须要在抽象类里,否则报错:Abstract method in non-abstract class
public abstract void doSomething();

public void hello(){}//抽象类中可以写普通方法,继承的子类也不需要一定重写
}


public class A extends Action{
//提示:Class 'A' must either be declared abstract or implement abstract method 'doSomething()' in 'Action'
//继承了抽象类的子类必须实现原抽象类里的所有抽象方法,除非这个继承类也是一个抽象类
@Override
public void doSomething() {
}
}
  1. 不能new抽象类,只能靠子类去实现,抽象类仅作为一种约束。
  2. 抽象类中可以写普通方法
  3. 抽象方法必须在抽象类中
  4. 意义:提高开放效率&可扩展性

类是单继承的,接口是多继承的——所以抽象类其实用得不多

接口

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范(声明定义),自己无法写方法,约束和实现分离(生产环境惯例:面向接口编程

接口就是规范,定义的是一组规则,体现了现实世界里“如果你是……则必须能……”的思想。

接口的本质是契约,正如人类的法律一样制定好后大家都遵守。

OO的精髓是对对象的抽象——最能体现这一点的正是接口。

声明类的关键字是class,声明接口的关键字是interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface UserService {

//接口中所有的属性默认都是public static final的,全局静态常量
//直接写属性变量类型+名字+值即可
//一般不会在接口里定义常量
int AGE = 99;

//接口中所有的方法默认都是public abstract的
//直接写返回值类型+方法名+形参即可
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}

public interface TimeService {
void timer();
}

实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//接口都需要有实现类
//类 implements 接口
//实现了接口的类就必须要重写接口的所有方法
//抽象类extends只能单继承,接口可以多继承
public class UserServiceImpl implements UserService,TimeService {
@Override
public void timer() {

}

@Override
public void add(String name) {

}

@Override
public void delete(String name) {

}

@Override
public void update(String name) {

}

@Override
public void query(String name) {

}
}

总结:

  • 接口作为约束
  • 定义一些方法,让不同的人实现
  • 接口不能被实例化,因为接口里没有构造方法
  • implements可以实现多个接口,从而实现多继承
  • 接口的实现类必须要重写接口中的所有方法

IDEA重写接口方法快捷键:Ctrl+I或Alt+insert选择Implement method。

内部类

内部类:在一个类的内部再定义一个类。(若A类中定义了一个B类,那么B类相对于A类来说就称为内部类,A类相对于B类来说称为外部类。)

成员内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类方法");
}

public class Inner{
public void in(){
System.out.println("这是内部类方法");
}

//内部类可以直接访问外部类的私有变量
public void getID(){
System.out.println(id);
}

}
}

main测试:

1
2
3
4
5
6
7
8
9
10
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类的实例化对象来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
}

静态内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类方法");
}

public static class Inner{
public void in(){
System.out.println("这是内部类方法");
}

//加上static之后的静态内部类无法访问外部类的非静态、私有变量
//因为该内部类实例化在对象之前
//以下方法报错:
/*
public void getID(){
System.out.println(id);
}
*/
}
}

main:

1
2
3
4
5
6
7
8
9
10
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//Outer.Inner inner = outer.new Inner();报错Qualified new of static class,意为你能直接new一个静态内部类,就别通过外部类的实例了。
//通过外部类直接实例化静态内部类
Outer.Inner inner = new Outer.Inner();
inner.in();
//inner.getID();
}
}

局部内部类

1
2
3
4
5
6
7
8
9
10
public class Outer {

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

匿名内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test {
public static void main(String[] args) {
//匿名内部类:没有名字初始化类,不用把实例保存到变量中
new Apple().eat();

new UserService(){
@Override
public void hello() {
}
};
}
}

class Apple{
public void eat(){
System.out.println("eat");
}
}

interface UserService{
void hello();
}