面向对象3

​ 本篇主要介绍了抽象类、

抽象类

应用场景

为什么使用抽象类

​ 1:定义Dog类

​ 有颜色属性和叫的方法

​ 2:定义Bird类

​ 有颜色属性和叫的方法

​ 3:定义其父类Animal

​ 1:抽取共性颜色属性和叫的方法

​ 1:颜色的属性可以使用默认初始化值。

​ 2:叫的方法在父类中如何定义?

​ 1:狗是旺旺

​ 2:鸟是叽叽喳喳

​ 3:可以将父类的方法定义为狗叫让鸟继承父类重写叫的方法

​ 1:鸟怎么确定是否要重写父类方法。

2:不重写,编译和运行都没有问题,只是执行鸟叫的方法就会出现狗叫

​ 4:父类的方法很难确定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> abstract class Animal {
> String color;
>
> abstract void shout();
> }
>
> class Dog extends Animal {
>
> void shout() {
> System.out.println("旺旺");
> }
>
> }
>
> class Bird extends Animal {
>
> void shout() {
> System.out.println("叽叽喳喳");
> }
> }
>

>

抽象类的介绍

5:当描述一个类的时候,如果不能确定功能函数如何定义,那么该类就可以定义为抽象类,功能函数应该描述为抽象函数。

6:抽象类的特点

​ 1:有抽象函数的类,该类一定是抽象类。

​ 2:抽象类中不一定要有抽象函数。

​ 3:抽象类不能使用new创建对象

​ 1:创建对象,使用对象的功能,抽象类的方法,没有方法体。

​ 4:抽象类主要为了提高代码的复用性,让子类继承来使用。

​ 5:编译器强制子类实现抽象类父类的未实现的方法。

​ 1:可以不实现,前提是子类的也要声明为抽象的。

7:抽象的优点

​ 1:提高代码复用性

​ 2:强制子类实现父类中没有实现的功能

​ 2:提高代码的扩展性,便于后期的代码维护

8:抽象类不能创建对象,那么抽象类中是否有构造函数?

​ 1:抽象类中一定有构造函数。主要为了初始化抽象类中的属性。通常由子类实现。

9:final和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
> abstract class Animal {
>
> String name;
>
> // 抽象类可以有构造函数
> Animal() {
>
> }
>
> Animal(String name) {
> this.name = name;
> }
>
> abstract void shout();
>
> }
>
> class Dog extends Animal {
> Dog() {
>
> }
>
> Dog(String name) {
> super(name);
> }
>
> void shout() {
> System.out.println("旺旺");
>
> }
> }
>
> class Demo3 {
> public static void main(String[] args) {
> // 抽象类不能创建对象
> // Animal a=new Animal();
> Dog d = new Dog("旺财");
> System.out.println();
> }
> }
>

>

注意细节

抽象类可以没有抽象方法(java.awt.*的类就是这样子操作的)。

抽象类可以继承普通类与抽象类。

抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化。

抽象类一定有构造方法。

abstract与其他修饰符的关系:

final与abstract不能共存:

​ final:它的作用 修饰类代表不可以继承 修饰方法不可重写

​ abstract修饰类就是用来被继承的,修饰方法就是用来被重写的。

static static修饰的方法可以用类名调用,

​ 对于abstract修饰的方法没有具体的方法实现,所有不能直接调用,

​ 也就是说不可以与static共存。

private**

​ private修饰的只能在本类中使用,

​ abstract方法是用来被子类进行重写的,有矛盾

​ 所有不能共存.

练习:使用抽象类计算一个矩形与圆形的面积。

##四种类型的值交换

基本类型的交换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test {
public static void main(String[] args) {
int a=10;
int b=20;
System.out.println("交换值之前:a="+a+" "+" b="+b);
change(a, b);
System.out.println("交换值之后:a="+a+" "+" b="+b);
}
public static void change(int a,int b){
int temp=a;
a=b;
b=temp;
}
}
//结果:发现交换值前后没有变量的值发生变化。

原因分析

img

数组类型的交换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
public static void main(String[] args) {
int [] arr={1,2,3,4,5};
System.out.println("交换值之前:"+Arrays.toString(arr));
change(arr, 1,3);
System.out.println("交换值之后:"+Arrays.toString(arr));
}
public static void change(int []arr,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
//结果:交换值成功。

原因分析

img

对象类型的交换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Te{
int x=10;
public Te(int x) {
this.x = x;
}
}
public class Test {
public static void main(String[] args) {
Te test=new Te(1);
System.out.println("交换值之前:"+test.x);
change(test, 4);
System.out.println("交换值之后:"+test.x);
}
public static void change(Te test,int x){
test.x=x;
}
}
//结果:交换成功

原因分析

img

字符串类型的值交换

img

值交换失败。字符串中的值存在常量池中。

img

接口

概述

img

接口(interface):usb接口,主要是使用来拓展笔记本的功能,那么在java中的接口主要是使用来拓展定义类的功能,可以弥补java中单继承的缺点。

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
class Pencil {
String name;
Pencil() {
}
Pencil(String name) {
this.name = name;
}
void write() {
System.out.println("写字");
}
}
interface Eraser {
public static final String color = "白色";
public abstract void clean();
}
// 1:带橡皮的铅笔类继承铅笔类实现橡皮接口
class PencilWithEraser extends Pencil implements Eraser {
PencilWithEraser() {
}
PencilWithEraser(String name) {
super(name);
}
void write() {
System.out.println(name + ":考试专用");
}
public void clean() {
System.out.println(super.name + ":带橡皮的铅笔,就是好用");
}
}
class Demo6 {
public static void main(String[] args) {
PencilWithEraser pe = new PencilWithEraser("中华2B");
pe.write();
pe.clean();
System.out.println(pe.color);
System.out.println(PencilWithEraser.color);
}
}

格式

1
2
3
4
5
6
> interface Inter
> {
> int num = 6; //可以定义属性与方法。
> void show();
> }
>

>

注意:可以通过javap命令查看.

  1. 接口中的所有属性 默认的修饰符是 public static final。

  2. 接口中的所有方法 默认的修饰符是 public abstract。

疑惑:干嘛不在PencilWithEraser添加remove功能函数,而要通过接口?

img

接口的特点

  1. 类实现接口可以通过implements实现,实现接口的时候必须把接口中的所有方法实现,一个类可以实现多个接口。

  2. 接口中定义的所有的属性默认是public static final的,即静态常量既然是常量,那么定义的时候必须赋值。

  3. 接口中定义的方法不能有方法体。接口中定义的方法默认添加public abstract

  4. 有抽象函数的不一定是抽象类,也可以是接口类。

  5. 由于接口中的方法默认都是抽象的,所以不能被实例化。

  6. 对于接口而言,可以使用子类来实现接口中未被实现的功能函数。

  7. 如果实现类中要访问接口中的成员,不能使用super关键字。因为两者之间没有显示的继承关系,况且接口中的成员成员属性是静态的。可以使用接口名直接访问。

  8. 接口没有构造方法。

接口与类、接口之间的关系

1、接口与类之间是实现关系。

大家之前都知道类与类之间的关系继承,那么接口与类之间又是怎样子的关系呢?接口与类之间是实现关系。非抽象类实现接口时,必须把接口里面的所有方法实现。类实现接口用关键字implments,类与接口之间是可以多实现的(即一个类可以实现多个接口)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface Eraser {
public static final String color = "白色";
public abstract void clean();
}
class Pencil implements Eraser {
String name;
Pencil() {
}
Pencil(String name) {
this.name = name;
}
void write() {
System.out.println("写字");
}
@Override
public void clean() {
System.out.println("涂改...");
}
}

分析:

​ 原本铅笔没有涂改功能的,但是一旦实现了Eraser接口做了实现,那么就具备了涂改功能,那么接口的作用则是拓展功能。

  1. 接口与接口之间的关系式继承。
1
2
3
4
5
6
7
8
9
interface A{
public void show();
}
interface B{
public void print();
}
interface C extends A,B{
}

接口与接口之间的关系是继承,接口可以多继承接口.

练习:在现实生活中有部分同学在学校期间只会学习,但是有部分学生除了学习外还会赚钱。

多态

概述

1:什么是多态

​ 一个对象的多种状态

​ (老师)(员工)(儿子)

​ 教师 a =老钟;

​ 员工 b= 老钟;

​ 2:多态体现

​ 1:Father类

​ 1:非静态成员变量x

​ 2:静态成员变量y

​ 3:非静态方法eat,方法体输出父类信息

​ 4:静态方法speak();方法体输出父类信息

​ 2:Son类

​ 1:非静态成员变量x

​ 2:静态成员变量y

​ 3:非静态方法eat,方法体输出子类信息

​ 4:静态方法speak();方法体输出子类信息

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
class Father {
int x = 1;
static int y = 2;
void eat() {
System.out.println("开吃");
}
static void speak() {
System.out.println("小头爸爸");
}
}
class Son extends Father {
int x = 3;
static int y = 4;
void eat() {
System.out.println("大头儿子很能吃");
}
static void speak() {
System.out.println("大头儿子。");
}
}
class Demo10 {
public static void main(String[] args) {
Father f = new Son(); // 父类引用指向了子类对象。
System.out.println(f.x); // 1
System.out.println(f.y); // 2
f.eat(); // 输出的是子类的。
f.speak(); // 输出的是父类
}
}

3:Son类继承父类

​ 1:创建Father f=new Son();

​ 1:这就是父类引用指向了子类对象。

​ 2:问f.x=?(非静态)

​ 3:问f.y=?(静态)

​ 4:问f.eat()输出的是子类还是父类信息?(非静态)

​ 5:问f.speak()输出的是子类还是父类信息?(静态)

​ 4:总结

1:当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量

2:当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量

​ 所以:父类和子类有相同的成员变量,多态下访问的是父类的成员变量。

3:当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。

4:当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 抽象类
    1. 1.1. 应用场景
    2. 1.2. 抽象类的介绍
    3. 1.3. 注意细节
    4. 1.4. 基本类型的交换
    5. 1.5. 数组类型的交换
    6. 1.6. 对象类型的交换
    7. 1.7. 字符串类型的值交换
  2. 2. 接口
    1. 2.1. 概述
    2. 2.2. 接口的特点
    3. 2.3. 接口与类、接口之间的关系
  3. 3. 多态
    1. 3.1. 概述
Fork me on GitHub