0%

java学习笔记1——面向对象

面向对象

面向对象编程有三大特性:封装、继承、多态。

类的封装

类的封装十分简单,就是创建一个类,将类的功能写完,供别的类实例化调用即可,他的作用就是隐藏功能的细节,仅提供功能,如以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Func {
public int mul(int a, int b)
{
int sum = 0;
for (int i = 0; i < b; i++) {
sum += a;
}
return sum;
}
}


public class main {
public static void main(String[] args) {
Func func = new Func();
System.out.println(func.mul(3,2));
}
}

这个封装的类Func功能就是将两个数相乘,但是只看主函数是不知道Func是如何将两个数相乘的,有可能是直接return a * b,也有可能像上面一样,所以封装的类是隐藏了实现细节的。

类的继承

如果我现在想创建一个类,而且已经有一个现成的类具备了部分我想创建的类的功能,那我就可以直接继承他的所有功能,并且还可以额外增加自己的功能。

继承的关键字是extends,如果你想继承一个类,写法是这样的:

1
2
3
class zi extends fu{
//代码
}

这样就继承了fu类,zi可以用fu类的功能,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Fudemo {
public void Fu(){
System.out.println("这是父类方法");
}
}

public class Zidemo extends Fudemo{
public void Zi(){
System.out.println("这是子类方法");
}
}

public class main {
public static void main(String[] args) {
Zidemo zi = new Zidemo();
zi.Fu();
zi.Zi();
}
}

执行结果

方法重写

如果我想在子类里写一个和父类名称相同的方法,这种操作叫做重写。

要注意一点,重写的方法修饰权限必须要比原方法一致或更高。
而返回值类型必须与原方法范围一致或更小。

1
2
3
4
5
6
7
8
9
10
public class Zidemo extends Fudemo{
public void Zi(){
System.out.println("这是子类方法");
}
@Override
public void Fu(){
System.out.println("这是重写父类方法");

}
}

我们重写了Fu方法,这样我们用zi.Fu()调用时就会调用我们重写的方法,

执行结果2

@override是注解,在重写方法前写上可以检验重写是否正确(但是不写注解不影响执行)。

那我们在重写了方法后,还可以使用原方法吗?用super关键字就可以。

1
2
3
4
5
6
7
8
9
10
11
public class Zidemo extends Fudemo{
public void Zi(){
System.out.println("这是子类方法");
}
@Override
public void Fu(){
super.Fu();
System.out.println("这是重写父类方法");

}
}

这样我们就会在重写方法前调用原Fu方法:

执行结果3

用super还可以调用父类的参数:

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


public class Zidemo extends Fudemo{
int num = 20;
public void Zi(){
System.out.println("这是子类方法");
}
@Override
public void Fu(){
System.out.println(super.num);
System.out.println(num);
System.out.println("这是重写父类方法");

}
}

可以看到结果:

执行结果4

tips:object类是所有类的父类,我们写类的时候无需写extends object

类的多态
重载

重载非常简单,即为多个方法使用相同的方法名,根据传回的参数个数和类型不同调用不同的方法,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class adddemo {
public int add(int a, int b){
return a + b;
}
public int add(int a, int b, int c){
return a + b + c;
}
public int add(int a, int b, int c, int d){
return a + b + c + d;
}
}

public class main {
public static void main(String[] args) {
adddemo add = new adddemo();
System.out.println(add.add(1,2));
System.out.println(add.add(1,2,3));
System.out.println(add.add(1,2,3,4));
}
}

执行结果5

构成重载的条件:

  1. 参数类型不同
  2. 参数个数不同
  3. 不同类型参数顺序不同
向上转型

如果现在有一个方法的参数是a类的实例,b是a类子类,那么b类的实例也可以作为参数,因为子类完全具备父类的各种特征,如平行四边形完全符合四边形的定义。

向下转型

四边形不一定是平行四边形,所以我们要先进行检验他是不是平行四边形,我们要用到的关键字是instanceof,这个关键字可以检验一个实例对象是否属于一个类大概用法:

1
四边形A instanceof 平行四边形

如果A是的话,我们还要进行一步强制转换类型,就可以了:

1
平行四边形 平行四边形A = (平行四边形) 四边形A;
抽象类

四边形可以是一个具体的类吗?平行四边形、矩形、梯形这些都可以是四边形的具体类,那么我们可以把四边形定义为一个抽象类,这个类的意义就是被继承,他里面的所有方法都没有任何代码,只有方法名和参数,他的意义也只是被重写。

定义一个抽象类的关键字是abstract,

1
2
3
abstract class classdemo{
public abstract void func1(int a. int b);
}

这样的类的唯一意义就是被继承,而且继承自他的子类必须重写里面的所有用abstract关键字的方法。

接口

一个类不能有多个父类,如果抽象类中有我用不到的方法,那我也只能重写,如果拿出去的话,我不能继承两个类,这时候接口就十分有用。

接口用interface定义:

1
2
3
4
interface 接口名 [extends 父接口名1,父接口名2]{
public [staticfinal] 常量;
public abstract 方法;
}

例:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
public interface Father{
void smoking();
void fishing();
}

public interface Mother{
void cooking();
void watchTV();
}

public class son implements Father, Mother{

@Override
public void smoking() {
System.out.println("我爱抽烟");
}

@Override
public void fishing() {
System.out.println("我爱钓鱼");
}

@Override
public void cooking() {
System.out.println("我爱做饭");
}

@Override
public void watchTV() {
System.out.println("我爱看电视");
}

}

public class main{
public static void main(String[] args) {
son son1 = new son();
son1.cooking();
son1.fishing();
son1.smoking();
son1.watchTV();
}
}

执行结果6

可见接口可以继承多个,儿子继承了Father和Mother接口。

那么抽象类和接口除了继承一个和继承多个以外还有什么区别呢?

抽象类 接口
方法 可以有非抽象方法 全为抽象方法
属性 可以有非静态常量 全为静态常量
构造方法

未完待续。。。