Java基础知识
Drunkbaby Lv6

Java基础知识

Java基础知识

0x01 前言

学习 Java 反射的过程中,发现自己对 Java 对象,类,函数,重写,重载什么的,还是不是特别清晰,于是打算再过一遍。

  • 之前为了考试,主要是在看重写重载吧,却把大头给丢了。

或多或少希望能帮上师傅们一点。

0x02 Java 一些概念

1. Java 方法

简单来说,方法就是面向对象版的函数。可以传参,可以 return。

Main 方法也是方法,就是我们平常看到的这个

1
2
public static void main(String[] args){
}

Java 方法的调用

主要分为三种方法,静态,非静态,构造方法。

静态方法 static

比较简单,就和函数的利用是一样的。
如果是同一个文件,直接调用即可。
如果不是同一个文件,则直接使用 对象名.方法即可

  • 有个缺点,不能使用 this 和 super 关键字
非静态方法

如果是非静态方法就需要先实例化对象,也就是 new

方法的重载

✨ 重载就是在一个类中,有相同的函数名称,但形参不同的函数

必须保证名字相同;参数类型不同。
参数数量可以不同,内容也可以不同。

2. Java 类

.class 文件就是类,类中包含了一堆对象,而对象则是最初不存在的,需要我们创建的。

  • 先有类,再有对象

3. Java 对象

是创建于类的基础上的,比如我们的 new 操作

1
Person per = new Person();
  • 一些基础性的知识就先不聊了,直接看一些累人的概念

0x03 类的继承

1. 继承的关键字

我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承 object(这个类在 ** java.lang 包中,所以不需要 import**)祖先类。

类 extends 关键字的用法:

extends 关键字较为简单

1
2
3
4
5
class 父类{
}

class 子类 extends 父类{
}

子类可以继承父类的非 private 的属性与方法。子类可以用自己的方式实现父类的方法。

Java 中只有单继承,没有多继承。
一个子类只能继承一个父类,一个父类可以给多个子类继承。

Object 类

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

super

super 是和 this 相对的,对变量适用,对方法也适用

1
2
3
4
5
6
7
8
public class Student extends Person{

public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}

一写出来就很清晰了。

  • 在写子类的无参构造之前必须写父类的无参构造。
  • 不能同时调用构造方法。

  • 类 implements 关键字的用法

implements 只用于接口的继承

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface A 
{
public void eat();
public void sleep();
}
public interface B
{
public void show();
}
public class C implements A,B
{

}
  • this 与 super 关键字

调用父类的方法时,需要用 super。子类方法可以直接调用,或用 this 关键字。

  • final 关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写
final 关键字声名类与方法

声名类:

1
final class 类名 {//类体}

声名方法:

1
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

: 实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final。

2. 构造器

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

也就是子类在使用构造函数时,必须先调用一遍父类的构造函数。


0x04 类中方法的重写与重载

1. 类中方法的重写

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

父类的引用指向子类

假设 A 继承了 B

1
2
3
4
5
A a = new A();
a.test();

B b = new A();
b.test();

非静态方法只输出 A

重写规则

  • 参数列表与被重写方法的参数列表必须完全相同。

  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。

  • 父类的成员方法只能被它的子类重写。

  • 声明为 final 的方法不能被重写。

  • 声明为 static 的方法不能被重写,但是能够被再次声明。

  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

  • 构造方法不能被重写。

  • 如果不能继承一个类,则不能重写该类的方法。

2. 类中方法的重载

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

重载规则

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

用一张图生动得描绘一下Java重写和重载的区别


0x05 抽象类

抽象类和普通的类大体上没有什么不同。
主要的差别在于,抽象类不可以直接实例化对象。所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

1. 抽象类的抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
Abstract关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

范例代码如下:

1
2
3
4
5
6
7
8
public abstract class Employee 
{ private String name;
private String address;
private int number;

public abstract double computePay();
//其余代码
}

声明抽象方法会造成以下两个结果:

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

2. 抽象类总结规定

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

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

  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。


0x06 接口

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口的声明语法格式如下:

1
2
3
4
5
[可见度] interface 接口名称 [extends 其他的接口名] 
{
// 声明变量
// 抽象方法
}

接口更类似于抽象类

1. 抽象类和接口的区别

    1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
    1. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
    1. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
    1. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2. 接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用 implements 关键字实现接口。在类声明中,Implements 关键字放在 class 声明后面。

实际代码如范例所示

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
interface Animal 
{
public void eat();
public void travel();
}
public class MammalInt implements Animal
{
public void eat() {
System.out.println("Mammal eats");
}

public void travel() {
System.out.println("Mammal travels");
}

public int noOfLegs() {
return 0;
}

public static void main(String args[]) {
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}

以上实例编译运行结果如下:

1
2
Mammal eats 
Mammal travels

3. 接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。

下面的 Sports 接口被 Hockey 和 Football 接口继承:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 文件名: Sports.java
public interface Sports {
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}

// 文件名: Football.java
public interface Football extends Sports {
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}

// 文件名: Hockey.java
public interface Hockey extends Sports {
public void homeGoalScored();
public void visitingGoalScored();
public void endOfPeriod(int period);
public void overtimePeriod(int ot);
}

Hockey 接口自己声明了四个方法,从 Sports 接口继承了两个方法,这样,实现 Hockey 接口的类需要实现六个方法。
相似的,实现 Football 接口的类需要实现五个方法,其中两个来自于 Sports 接口。

0x07 Defalut 类

是可以被外部调用的,和 public 差不多,这个类型的类最初设计出来,是用来提高类中同名方法的优先级的。具体的可以看这一篇文章

https://cloud.tencent.com/developer/article/1590920

 评论