Java基础-09总结final,多态,抽象类,接口

你需要的是什么,直接评论留言。

获取更多资源加微信公众号“Java帮帮” (是公众号,不是微信好友哦)

还有“Java帮帮”今日头条号,技术文章与新闻,每日更新,欢迎阅读

学习交流请加Java帮帮交流553841695

分享是一种美德,分享更快乐!

1:final关键字(掌握)

(1)是最终的意思,可以修饰类,方法,变量。

(2)特点:

A:它修饰的类,不能被继承。

B:它修饰的方法,不能被重写。

C:它修饰的变量,是一个常量。


/*

final可以修饰类,方法,变量

特点:

final可以修饰类,该类不能被继承。

final可以修饰方法,该方法不能被重写。(覆盖,复写)

final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。

常量:

A:字面值常量

"hello",10,true

B:自定义常量

final int x = 10;

*/


//final class Fu //无法从最终Fu进行继承


class Fu {

public int num = 10;

public final int num2 = 20;


/*

public final void show() {

}

*/

}


class Zi extends Fu {

// Zi中的show()无法覆盖Fu中的show()

public void show() {

num = 100;

System.out.println(num);

//无法为最终变量num2分配值

//num2 = 200;

System.out.println(num2);

}

}


class FinalDemo {

public static void main(String[] args) {

Zi z = new Zi();

z.show();

}

}


/*

继承的代码体现

由于继承中方法有一个现象:方法重写。

所以,父类的功能,就会被子类给覆盖调。

有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。

这个时候,针对这种情况,Java就提供了一个关键字:final

final:最终的意思。常见的是它可以修饰类,方法,变量。

*/

class Fu {

public final void show() {

System.out.println("这里是绝密资源,任何人都不能修改");

}

}


class Zi extends Fu {

// Zi中的show()无法覆盖Fu中的show()

public void show() {

System.out.println("这是一堆垃圾");

}

}


class ZiDemo {

public static void main(String[] args) {

Zi z = new Zi();

z.show();

}

}



(3)面试相关:

A:局部变量

a:基本类型 值不能发生改变

b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的

B:初始化时机

a:只能初始化一次。

b:常见的给值

定义的时候。(推荐)

构造方法中。


/*

面试题:final修饰局部变量的问题

基本类型:基本类型的值不能发生改变。

引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。

*/

class Student {

int age = 10;

}


class FinalTest {

public static void main(String[] args) {

//局部变量是基本数据类型

int x = 10;

x = 100;

System.out.println(x);

final int y = 10;

//无法为最终变量y分配值

//y = 100;

System.out.println(y);

System.out.println("--------------");

//局部变量是引用数据类型

Student s = new Student();

System.out.println(s.age);

s.age = 100;

System.out.println(s.age);

System.out.println("--------------");

final Student ss = new Student();

System.out.println(ss.age);

ss.age = 100;

System.out.println(ss.age);

//重新分配内存空间

//无法为最终变量ss分配值

ss = new Student();

}

}


/*

final修饰变量的初始化时机

A:被final修饰的变量只能赋值一次。

B:在构造方法完毕前。(非静态的常量)

*/

class Demo {

//int num = 10;

//final int num2 = 20;

int num;

final int num2;

{

//num2 = 10;

}

public Demo() {

num = 100;

//无法为最终变量num2分配值

num2 = 200;

}

}


class FinalTest2 {

public static void main(String[] args) {

Demo d = new Demo();

System.out.println(d.num);

System.out.println(d.num2);

}

}


2:多态(掌握)

(1)同一个对象在不同时刻体现出来的不同状态。

(2)多态的前提:

A:有继承或者实现关系。

B:有方法重写。

C:有父类或者父接口引用指向子类对象。

多态的分类:

a:具体类多态

class Fu {}

class Zi extends Fu {}

Fu f = new Zi();

b:抽象类多态

abstract class Fu {}

class Zi extends Fu {}

Fu f = new Zi();

c:接口多态

interface Fu {}

class Zi implements Fu {}

Fu f = new Zi();

(3)多态中的成员访问特点

A:成员变量

编译看左边,运行看左边

B:构造方法

子类的构造都会默认访问父类构造

C:成员方法

编译看左边,运行看右边

D:静态方法

编译看左边,运行看左边

为什么?/*

多态:同一个对象(事物),在不同时刻体现出来的不同状态。

举例:

猫是猫,猫是动物。

水(液体,固体,气态)。

多态的前提:

A:要有继承关系。

B:要有方法重写。

其实没有也是可以的,但是如果没有这个就没有意义。

动物 d = new 猫();

d.show();

动物 d = new 狗();

d.show();

C:要有父类引用指向子类对象。

父 f = new 子();

用代码体现一下多态。

多态中的成员访问特点:

A:成员变量

编译看左边,运行看左边。

B:构造方法

创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。

C:成员方法

编译看左边,运行看右边。

D:静态方法

编译看左边,运行看左边。

(静态和类相关,算不上重写,所以,访问还是左边的)

由于成员方法存在方法重写,所以它运行看右边。

*/

class Fu {

public int num = 100;


public void show() {

System.out.println("show Fu");

}

public static void function() {

System.out.println("function Fu");

}

}


class Zi extends Fu {

public int num = 1000;

public int num2 = 200;


public void show() {

System.out.println("show Zi");

}

public void method() {

System.out.println("method zi");

}

public static void function() {

System.out.println("function Zi");

}

}


class DuoTaiDemo {

public static void main(String[] args) {

//要有父类引用指向子类对象。

//父 f = new 子();

Fu f = new Zi();

System.out.println(f.num);

//找不到符号

//System.out.println(f.num2);

f.show();

//找不到符号

//f.method();

f.function();

}

}

因为成员方法有重写。




(4)多态的好处:

A:提高代码的维护性(继承体现)

B:提高代码的扩展性(多态体现)


/*

多态的好处:

A:提高了代码的维护性(继承保证)

B:提高了代码的扩展性(由多态保证)

猫狗案例代码

*/

class Animal {

public void eat(){

System.out.println("eat");

}

public void sleep(){

System.out.println("sleep");

}

}


class Dog extends Animal {

public void eat(){

System.out.println("狗吃肉");

}

public void sleep(){

System.out.println("狗站着睡觉");

}

}


class Cat extends Animal {

public void eat() {

System.out.println("猫吃鱼");

}

public void sleep() {

System.out.println("猫趴着睡觉");

}

}


class Pig extends Animal {

public void eat() {

System.out.println("猪吃白菜");

}

public void sleep() {

System.out.println("猪侧着睡");

}

}


//针对动物操作的工具类

class AnimalTool {

private AnimalTool(){}


/*

//调用猫的功能

public static void useCat(Cat c) {

c.eat();

c.sleep();

}

//调用狗的功能

public static void useDog(Dog d) {

d.eat();

d.sleep();

}

//调用猪的功能

public static void usePig(Pig p) {

p.eat();

p.sleep();

}

*/

public static void useAnimal(Animal a) {

a.eat();

a.sleep();

}

}


class DuoTaiDemo2 {

public static void main(String[] args) {

//我喜欢猫,就养了一只

Cat c = new Cat();

c.eat();

c.sleep();

//我很喜欢猫,所以,又养了一只

Cat c2 = new Cat();

c2.eat();

c2.sleep();

//我特别喜欢猫,又养了一只

Cat c3 = new Cat();

c3.eat();

c3.sleep();

//...

System.out.println("--------------");

//问题来了,我养了很多只猫,每次创建对象是可以接受的

//但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。

//我们准备用方法改进

//调用方式改进版本

//useCat(c);

//useCat(c2);

//useCat(c3);

//AnimalTool.useCat(c);

//AnimalTool.useCat(c2);

//AnimalTool.useCat(c3);

AnimalTool.useAnimal(c);

AnimalTool.useAnimal(c2);

AnimalTool.useAnimal(c3);

System.out.println("--------------");

//我喜欢狗

Dog d = new Dog();

Dog d2 = new Dog();

Dog d3 = new Dog();

//AnimalTool.useDog(d);

//AnimalTool.useDog(d2);

//AnimalTool.useDog(d3);

AnimalTool.useAnimal(d);

AnimalTool.useAnimal(d2);

AnimalTool.useAnimal(d3);

System.out.println("--------------");

//我喜欢宠物猪

//定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用

Pig p = new Pig();

Pig p2 = new Pig();

Pig p3 = new Pig();

//AnimalTool.usePig(p);

//AnimalTool.usePig(p2);

//AnimalTool.usePig(p3);

AnimalTool.useAnimal(p);

AnimalTool.useAnimal(p2);

AnimalTool.useAnimal(p3);

System.out.println("--------------");

//我喜欢宠物狼,老虎,豹子...

//定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用

//前面几个必须写,我是没有意见的

//但是,工具类每次都改,麻烦不

//我就想,你能不能不改了

//太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?

//改用另一种解决方案。

}

/*

//调用猫的功能

public static void useCat(Cat c) {

c.eat();

c.sleep();

}

//调用狗的功能

public static void useDog(Dog d) {

d.eat();

d.sleep();

}

*/

}


(5)多态的弊端:

父不能使用子的特有功能。

现象:

子可以当作父使用,父不能当作子使用。


/*

多态的弊端:

不能使用子类的特有功能。

*/

class Fu {

public void show() {

System.out.println("show fu");

}

}


class Zi extends Fu {

public void show() {

System.out.println("show zi");

}

public void method() {

System.out.println("method zi");

}


}


class DuoTaiDemo3 {

public static void main(String[] args) {

//测试

Fu f = new Zi();

f.show();

f.method();

}

}/*

多态的弊端:

不能使用子类的特有功能。

我就想使用子类的特有功能?行不行?

行。

怎么用呢?

A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)

B:把父类的引用强制转换为子类的引用。(向下转型)

对象间的转型问题:

向上转型:

Fu f = new Zi();

向下转型:

Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。

*/

class Fu {

public void show() {

System.out.println("show fu");

}

}


class Zi extends Fu {

public void show() {

System.out.println("show zi");

}

public void method() {

System.out.println("method zi");

}


}


class DuoTaiDemo4 {

public static void main(String[] args) {

//测试

Fu f = new Zi();

f.show();

//f.method();

//创建子类对象

//Zi z = new Zi();

//z.show();

//z.method();

//你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?

//如果可以,但是如下

Zi z = (Zi)f;

z.show();

z.method();

}

}


(6)多态中的转型

A:向上转型

从子到父

B:向下转型

从父到子


/*

ClassCastException:类型转换异常

一般在多态的向下转型中容易出现

*/

class Animal {

public void eat(){}

}


class Dog extends Animal {

public void eat() {}

public void lookDoor() {

}

}


class Cat extends Animal {

public void eat() {

}

public void playGame() {

}

}


class DuoTaiDemo5 {

public static void main(String[] args) {

//内存中的是狗

Animal a = new Dog();

Dog d = (Dog)a;

//内存中是猫

a = new Cat();

Cat c = (Cat)a;

//内存中是猫

Dog dd = (Dog)a; //ClassCastException

}

}


(7)孔子装爹的案例帮助大家理解多态


多态的问题理解:

class 孔子爹 {

public int age = 40;

public void teach() {

System.out.println("讲解JavaSE");

}

}

class 孔子 extends 孔子爹 {

public int age = 20;

public void teach() {

System.out.println("讲解论语");

}

public void playGame() {

System.out.println("英雄联盟");

}

}

//Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了

//但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢?

//然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹

//向上转型

孔子爹 k爹 = new 孔子();

//到人家那里去了

System.out.println(k爹.age); //40

k爹.teach(); //讲解论语

//k爹.playGame(); //这是儿子才能做的

//讲完了,下班回家了

//脱下爹的装备,换上自己的装备

//向下转型

孔子 k = (孔子) k爹;

System.out.println(k.age); //20

k.teach(); //讲解论语

k.playGame(); //英雄联盟


(8)多态的练习

A:猫狗案例

B:老师和学生案例


/* A:

多态练习:猫狗案例

*/

class Animal {

public void eat(){

System.out.println("吃饭");

}

}


class Dog extends Animal {

public void eat() {

System.out.println("狗吃肉");

}

public void lookDoor() {

System.out.println("狗看门");

}

}


class Cat extends Animal {

public void eat() {

System.out.println("猫吃鱼");

}

public void playGame() {

System.out.println("猫捉迷藏");

}

}


class DuoTaiTest {

public static void main(String[] args) {

//定义为狗

Animal a = new Dog();

a.eat();

System.out.println("--------------");

//还原成狗

Dog d = (Dog)a;

d.eat();

d.lookDoor();

System.out.println("--------------");

//变成猫

a = new Cat();

a.eat();

System.out.println("--------------");

//还原成猫

Cat c = (Cat)a;

c.eat();

c.playGame();

System.out.println("--------------");

//演示错误的内容

//Dog dd = new Animal();

//Dog ddd = new Cat();

//ClassCastException

//Dog dd = (Dog)a;

}

}


/* 扩展(1)


不同地方饮食文化不同的案例

*/

class Person {

public void eat() {

System.out.println("吃饭");

}

}


class SouthPerson extends Person {

public void eat() {

System.out.println("炒菜,吃米饭");

}

public void jingShang() {

System.out.println("经商");

}

}


class NorthPerson extends Person {

public void eat() {

System.out.println("炖菜,吃馒头");

}

public void yanJiu() {

System.out.println("研究");

}

}


class DuoTaiTest2 {

public static void main(String[] args) {

//测试

//南方人

Person p = new SouthPerson();

p.eat();

System.out.println("-------------");

SouthPerson sp = (SouthPerson)p;

sp.eat();

sp.jingShang();

System.out.println("-------------");

//北方人

p = new NorthPerson();

p.eat();

System.out.println("-------------");

NorthPerson np = (NorthPerson)p;

np.eat();

np.yanJiu();

}

}


/*

看程序写结果:先判断有没有问题,如果没有,写出结果

*/

class Fu {

public void show() {

System.out.println("fu show");

}

}


class Zi extends Fu {

public void show() {

System.out.println("zi show");

}


public void method() {

System.out.println("zi method");

}

}


class DuoTaiTest3 {

public static void main(String[] args) {

Fu f = new Zi();

//找不到符号

//f.method();

f.show();

}

}


/*

看程序写结果:先判断有没有问题,如果没有,写出结果

多态的成员访问特点:

方法:编译看左边,运行看右边。

继承的时候:

子类中有和父类中一样的方法,叫重写。

子类中没有父亲中出现过的方法,方法就被继承过来了。

*/

class A {

public void show() {

show2();

}

public void show2() {

System.out.println("我");

}

}

class B extends A {

/*

public void show() {

show2();

}

*/


public void show2() {

System.out.println("爱");

}

}

class C extends B {

public void show() {

super.show();

}

public void show2() {

System.out.println("你");

}

}

public class DuoTaiTest4 {

public static void main(String[] args) {

A a = new B();

a.show();

B b = new C();

b.show();

}

}




3:抽象类(掌握)

(1)把多个共性的东西提取到一个类中,这是继承的做法。

但是呢,这多个共性的东西,在有些时候,方法声明一样,但是方法体。

也就是说,方法声明一样,但是每个具体的对象在具体实现的时候内容不一样。

所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。

而一个没有具体的方法体的方法是抽象的方法。

在一个类中如果有抽象方法,该类必须定义为抽象类。

(2)抽象类的特点

A:抽象类和抽象方法必须用关键字abstract修饰

B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类

C:抽象类不能实例化

D:抽象类的子类

a:是一个抽象类。

b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。


/*

抽象类的概述:

动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。

我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。

抽象类的特点:

A:抽象类和抽象方法必须用abstract关键字修饰

B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类

C:抽象类不能实例化

因为它不是具体的。

抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?

用于子类访问父类数据的初始化

D:抽象的子类

a:如果不想重写抽象方法,该子类是一个抽象类。

b:重写所有的抽象方法,这个时候子类是一个具体的类。

抽象类的实例化其实是靠具体的子类实现的。是多态的方式。

Animal a = new Cat();

*/


//abstract class Animal //抽象类的声明格式

abstract class Animal {

//抽象方法

//public abstract void eat(){} //空方法体,这个会报错。抽象方法不能有主体

public abstract void eat();

public Animal(){}

}


//子类是抽象类

abstract class Dog extends Animal {}


//子类是具体类,重写抽象方法

class Cat extends Animal {

public void eat() {

System.out.println("猫吃鱼");

}

}


class AbstractDemo {

public static void main(String[] args) {

//创建对象

//Animal是抽象的; 无法实例化

//Animal a = new Animal();

//通过多态的方式

Animal a = new Cat();

a.eat();

}

}


(3)抽象类的成员特点:

A:成员变量

有变量,有常量

B:构造方法

有构造方法

C:成员方法

有抽象,有非抽象


/*

抽象类的成员特点:

成员变量:既可以是变量,也可以是常量。

构造方法:有。

用于子类访问父类数据的初始化。

成员方法:既可以是抽象的,也可以是非抽象的。

抽象类的成员方法特性:

A:抽象方法 强制要求子类做的事情。

B:非抽象方法 子类继承的事情,提高代码复用性。

*/

abstract class Animal {

public int num = 10;

public final int num2 = 20;


public Animal() {}

public Animal(String name,int age){}

public abstract void show();

public void method() {

System.out.println("method");

}

}


class Dog extends Animal {

public void show() {

System.out.println("show Dog");

}

}


class AbstractDemo2 {

public static void main(String[] args) {

//创建对象

Animal a = new Dog();

a.num = 100;

System.out.println(a.num);

//a.num2 = 200;

System.out.println(a.num2);

System.out.println("--------------");

a.show();

a.method();

}

}


(4)抽象类的练习

A:猫狗案例练习

B:老师案例练习

C:学生案例练习

D:员工案例练习


/* A:

猫狗案例

具体事物:猫,狗

共性:姓名,年龄,吃饭


分析:从具体到抽象

猫:

成员变量:姓名,年龄

构造方法:无参,带参

成员方法:吃饭(猫吃鱼)

狗:

成员变量:姓名,年龄

构造方法:无参,带参

成员方法:吃饭(狗吃肉)

因为有共性的内容,所以就提取了一个父类。动物。

但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的,

而方法是抽象的类,类就必须定义为抽象类。

抽象动物类:

成员变量:姓名,年龄

构造方法:无参,带参

成员方法:吃饭();

实现:从抽象到具体

动物类:

成员变量:姓名,年龄

构造方法:无参,带参

成员方法:吃饭();

狗类:

继承自动物类

重写吃饭();

猫类:

继承自动物类

重写吃饭();

*/

//定义抽象的动物类

abstract class Animal {

//姓名

private String name;

//年龄

private int age;

public Animal() {}

public Animal(String name,int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

//定义一个抽象方法

public abstract void eat();

}


//定义具体的狗类

class Dog extends Animal {

public Dog() {}

public Dog(String name,int age) {

super(name,age);

}

public void eat() {

System.out.println("狗吃肉");

}

}


//定义具体的猫类

class Cat extends Animal {

public Cat() {}

public Cat(String name,int age) {

super(name,age);

}

public void eat() {

System.out.println("猫吃鱼");

}

}


//测试类

class AbstractTest {

public static void main(String[] args) {

//测试狗类

//具体类用法

//方式1:

Dog d = new Dog();

d.setName("旺财");

d.setAge(3);

System.out.println(d.getName()+"---"+d.getAge());

d.eat();

//方式2:

Dog d2 = new Dog("旺财",3);

System.out.println(d2.getName()+"---"+d2.getAge());

d2.eat();

System.out.println("---------------------------");

Animal a = new Dog();

a.setName("旺财");

a.setAge(3);

System.out.println(a.getName()+"---"+a.getAge());

a.eat();

Animal a2 = new Dog("旺财",3);

System.out.println(a2.getName()+"---"+a2.getAge());

a2.eat();

//练习:测试猫类

}

}


/* B:

老师案例

具体事物:基础班老师,就业班老师

共性:姓名,年龄,讲课。


分析:

基础班老师

姓名,年龄

讲课。

就业班老师

姓名,年龄

讲课。

实现:

老师类

基础班老师

就业班老师

*/

//定义抽象的老师类

abstract class Teacher {

//姓名

private String name;

//年龄

private int age;

public Teacher() {}

public Teacher(String name,int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

//抽象方法

public abstract void teach();

}


//基础班老师类

class BasicTeacher extends Teacher {

public BasicTeacher(){}

public BasicTeacher(String name,int age) {

super(name,age);

}

public void teach() {

System.out.println("基础班老师讲解JavaSE");

}

}


//就业班老师类

class WorkTeacher extends Teacher {

public WorkTeacher(){}

public WorkTeacher(String name,int age) {

super(name,age);

}

public void teach() {

System.out.println("就业班老师讲解JavaEE");

}

}


class AbstractTest2 {

public static void main(String[] args) {

//具体的类测试,自己玩

//测试(多态)

//基础班老师

Teacher t = new BasicTeacher();

t.setName("刘意");

t.setAge(30);

System.out.println(t.getName()+"---"+t.getAge());

t.teach();

System.out.println("--------------");

t = new BasicTeacher("刘意",30);

System.out.println(t.getName()+"---"+t.getAge());

t.teach();

System.out.println("--------------");

//就业班老师

t = new WorkTeacher();

t.setName("林青霞");

t.setAge(27);

System.out.println(t.getName()+"---"+t.getAge());

t.teach();

System.out.println("--------------");

t = new WorkTeacher("林青霞",27);

System.out.println(t.getName()+"---"+t.getAge());

t.teach();

}

}


/* C:

学生案例

具体事务:基础班学员,就业班学员

共性:姓名,年龄,班级,学习,吃饭


分析:

基础班学员

成员变量:姓名,年龄,班级

成员方法:学习,吃饭

就业班学员

成员变量:姓名,年龄,班级

成员方法:学习,吃饭

得到一个学员类。

成员变量:姓名,年龄,班级

成员方法:学习,吃饭

实现:

学员类

基础班学员

就业班学员

*/

//定义抽象学员类

abstract class Student {

//姓名

private String name;

//年龄

private int age;

//班级

private String grand;

public Student() {}

public Student(String name,int age,String grand) {

this.name = name;

this.age = age;

this.grand = grand;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getGrand() {

return grand;

}

public void setGrand(String grand) {

this.grand = grand;

}

//学习

public abstract void study();

//吃饭

public void eat() {

System.out.println("学习累了,就该吃饭");

}

}


//具体基础班学员类

class BasicStudent extends Student {

public BasicStudent() {}

public BasicStudent(String name,int age,String grand) {

super(name,age,grand);

}

public void study() {

System.out.println("基础班学员学习的是JavaSE");

}

}


//具体就业班学员类

class WorkStudent extends Student {

public WorkStudent() {}

public WorkStudent(String name,int age,String grand) {

super(name,age,grand);

}

public void study() {

System.out.println("就业班学员学习的是JavaEE");

}

}


class AbstractTest3 {

public static void main(String[] args) {

//我仅仅测试基础班学员

//按照多态的方式测试

Student s = new BasicStudent();

s.setName("林青霞");

s.setAge(27);

s.setGrand("1111");

System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand());

s.study();

s.eat();

System.out.println("--------------");

s = new BasicStudent("武鑫",48,"1111");

System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand());

s.study();

s.eat();

//就业班测试留给自己玩

}

}


/* D:

假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。

经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。

请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。

分析:

普通员工类

成员变量:姓名、工号以及工资。

成员方法:工作

经理类:

成员变量:姓名、工号以及工资,奖金属性

成员方法:工作

实现:

员工类:

普通员工类:

经理类:

*/

//定义员工类

abstract class Employee {

//姓名、工号以及工资

private String name;

private String id;

private int salary;

public Employee() {}

public Employee(String name,String id,int salary) {

this.name = name;

this.id = id;

this.salary = salary;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public int getSalary() {

return salary;

}

public void setSalary(int salary) {

this.salary = salary;

}

//工作

public abstract void work();

}


//普通员工类

class Programmer extends Employee {

public Programmer(){}

public Programmer(String name,String id,int salary) {

super(name,id,salary);

}

public void work() {

System.out.println("按照需求写代码");

}

}


//经理类

class Manager extends Employee {

//奖金

private int money; //bonus 奖金


public Manager(){}

public Manager(String name,String id,int salary,int money) {

super(name,id,salary);

this.money = money;

}

public void work() {

System.out.println("跟客户谈需求");

}

public int getMoney() {

return money;

}

public void setMoney(int money) {

this.money = money;

}

}


class AbstractTest4 {

public static void main(String[] args) {

//测试普通员工

Employee emp = new Programmer();

emp.setName("林青霞");

emp.setId("czbk001");

emp.setSalary(18000);

System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());

emp.work();

System.out.println("-------------");

emp = new Programmer("林青霞","czbk001",18000);

System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());

emp.work();

System.out.println("-------------");

/*

emp = new Manager();

emp.setName("刘意");

emp.setId("czbk002");

emp.setSalary(8000);

emp.setMoney(2000);

*/

//由于子类有特有的内容,所以我们用子类来测试

Manager m = new Manager();

m.setName("刘意");

m.setId("czbk002");

m.setSalary(8000);

m.setMoney(2000);

System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());

m.work();

System.out.println("-------------");

//通过构造方法赋值

m = new Manager("刘意","czbk002",8000,2000);

System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());

m.work();

}

}


(5)抽象类的几个小问题

A:抽象类有构造方法,不能实例化,那么构造方法有什么用?

用于子类访问父类数据的初始化

B:一个类如果没有抽象方法,却定义为了抽象类,有什么用?

为了不让创建对象

C:abstract不能和哪些关键字共存

a:final 冲突

b:private 冲突

c:static 无意义


/*

一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?

A:可以。

B:不让创建对象。


abstract不能和哪些关键字共存?

private 冲突

final 冲突

static 无意义

*/

abstract class Fu {

//public abstract void show();

//非法的修饰符组合: abstract和private

//private abstract void show();

//非法的修饰符组合

//final abstract void show();

//非法的修饰符组合

static abstract void show();

public static void method() {

System.out.println("method");

}

}


class Zi extends Fu {

public void show() {}

}


class AbstractDemo3 {

public static void main(String[] args) {

Fu.method();

}

}

4:接口(掌握)

(1)回顾猫狗案例,它们仅仅提供一些基本功能。

比如:猫钻火圈,狗跳高等功能,不是动物本身就具备的,

是在后面的培养中训练出来的,这种额外的功能,java提供了接口表示。

(2)接口的特点:

A:接口用关键字interface修饰

interface 接口名 {}

B:类实现接口用implements修饰

class 类名 implements 接口名 {}

C:接口不能实例化

D:接口的实现类

a:是一个抽象类。

b:是一个具体类,这个类必须重写接口中的所有抽象方法。


/*

接口的特点:

A:接口用关键字interface表示

interface 接口名 {}

B:类实现接口用implements表示

class 类名 implements 接口名 {}

C:接口不能实例化

那么,接口如何实例化呢?

按照多态的方式来实例化。

D:接口的子类

a:可以是抽象类。但是意义不大。

b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

由此可见:

A:具体类多态(几乎没有)

B:抽象类多态(常用)

C:接口多态(最常用)

*/

//定义动物培训接口

interface AnimalTrain {

public abstract void jump();

}


//抽象类实现接口

abstract class Dog implements AnimalTrain {

}


//具体类实现接口

class Cat implements AnimalTrain {

public void jump() {

System.out.println("猫可以跳高了");

}

}


class InterfaceDemo {

public static void main(String[] args) {

//AnimalTrain是抽象的; 无法实例化

//AnimalTrain at = new AnimalTrain();

//at.jump();

AnimalTrain at = new Cat();

at.jump();

}

}


(3)接口的成员特点:

A:成员变量

只能是常量

默认修饰符:public static final

B:构造方法

没有构造方法

C:成员方法

只能是抽象的

默认修饰符:public abstract


/*

接口成员特点

成员变量;只能是常量,并且是静态的。

默认修饰符:public static final

建议:自己手动给出。

构造方法:接口没有构造方法。

成员方法:只能是抽象方法。

默认修饰符:public abstract

建议:自己手动给出。

所有的类都默认继承自一个类:Object。

类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。

*/

interface Inter {

public int num = 10;

public final int num2 = 20;

public static final int num3 = 30;

//错误: 需要<标识符>

//public Inter() {}

//接口方法不能带有主体

//public void show() {}


//abstract void show(); //默认public

public void show(); //默认abstract

}


//接口名+Impl这种格式是接口的实现类格式

/*

class InterImpl implements Inter {

public InterImpl() {

super();

}

}

*/


class InterImpl extends Object implements Inter {

public InterImpl() {

super();

}

public void show() {}

}


//测试类

class InterfaceDemo2 {

public static void main(String[] args) {

//创建对象

Inter i = new InterImpl();

System.out.println(i.num);

System.out.println(i.num2);

//i.num = 100;

//i.num2 = 200;

//System.out.println(i.num); //无法为最终变量num分配值

//System.out.println(i.num2);//无法为最终变量num2分配值

System.out.println(Inter.num);

System.out.println(Inter.num2);

System.out.println("--------------");

}

}


(4)类与类,类与接口,接口与接口

A:类与类

继承关系,只能单继承,可以多层继承

B:类与接口

实现关系,可以单实现,也可以多实现。

还可以在继承一个类的同时,实现多个接口

C:接口与接口

继承关系,可以单继承,也可以多继承


/*

类与类:

继承关系,只能单继承,可以多层继承。

类与接口:

实现关系,可以单实现,也可以多实现。

并且还可以在继承一个类的同时实现多个接口。

接口与接口:

继承关系,可以单继承,也可以多继承。

*/

interface Father {

public abstract void show();

}


interface Mother {

public abstract void show2();

}


interface Sister extends Father,Mother {


}


//class Son implements Father,Mother //多实现

class Son extends Object implements Father,Mother {

public void show() {

System.out.println("show son");

}

public void show2() {

System.out.println("show2 son");

}

}


class InterfaceDemo3 {

public static void main(String[] args) {

//创建对象

Father f = new Son();

f.show();

//f.show2(); //报错

Mother m = new Son();

//m.show(); //报错

m.show2();

}

}


(5)抽象类和接口的区别

A:成员区别

抽象类:

成员变量:可以变量,也可以常量

构造方法:有

成员方法:可以抽象,也可以非抽象

接口:

成员变量:只可以常量

成员方法:只可以抽象

B:关系区别

类与类

继承,单继承

类与接口

实现,单实现,多实现

接口与接口

继承,单继承,多继承

C:设计理念区别

抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。

接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。

(6)练习:

A:猫狗案例,加入跳高功能

B:老师和学生案例,加入抽烟功能0


/* A:

猫狗案例,加入跳高的额外功能

分析:从具体到抽象

猫:

姓名,年龄

吃饭,睡觉

狗:

姓名,年龄

吃饭,睡觉

由于有共性功能,所以,我们抽取出一个父类:

动物:

姓名,年龄

吃饭();

睡觉(){}

猫:继承自动物

狗:继承自动物

跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口

接口:

跳高

部分猫:实现跳高

部分狗:实现跳高

实现;

从抽象到具体

使用:

使用具体类

*/

//定义跳高接口

interface Jumpping {

//跳高功能

public abstract void jump();

}


//定义抽象类

abstract class Animal {

//姓名

private String name;

//年龄

private int age;

public Animal() {}

public Animal(String name,int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

//吃饭();

public abstract void eat();

//睡觉(){}

public void sleep() {

System.out.println("睡觉觉了");

}

}


//具体猫类

class Cat extends Animal {

public Cat(){}

public Cat(String name,int age) {

super(name,age);

}

public void eat() {

System.out.println("猫吃鱼");

}

}


//具体狗类

class Dog extends Animal {

public Dog(){}

public Dog(String name,int age) {

super(name,age);

}

public void eat() {

System.out.println("狗吃肉");

}

}


//有跳高功能的猫

class JumpCat extends Cat implements Jumpping {

public JumpCat() {}

public JumpCat(String name,int age) {

super(name,age);

}


public void jump() {

System.out.println("跳高猫");

}

}


//有跳高功能的狗

class JumpDog extends Dog implements Jumpping {

public JumpDog() {}

public JumpDog(String name,int age) {

super(name,age);

}


public void jump() {

System.out.println("跳高狗");

}

}


class InterfaceTest {

public static void main(String[] args) {

//定义跳高猫并测试

JumpCat jc = new JumpCat();

jc.setName("哆啦A梦");

jc.setAge(3);

System.out.println(jc.getName()+"---"+jc.getAge());

jc.eat();

jc.sleep();

jc.jump();

System.out.println("-----------------");

JumpCat jc2 = new JumpCat("加菲猫",2);

System.out.println(jc2.getName()+"---"+jc2.getAge());

jc2.eat();

jc2.sleep();

jc2.jump();

//定义跳高狗并进行测试的事情自己完成。

}

}


/* B:

老师和学生案例,加入抽烟的额外功能

分析:从具体到抽象

老师:姓名,年龄,吃饭,睡觉

学生:姓名,年龄,吃饭,睡觉

由于有共性功能,我们提取出一个父类,人类。

人类:

姓名,年龄

吃饭();

睡觉(){}

抽烟的额外功能不是人或者老师,或者学生一开始就应该具备的,所以,我们把它定义为接口

抽烟接口。


部分老师抽烟:实现抽烟接口

部分学生抽烟:实现抽烟接口

实现:从抽象到具体

使用:具体

*/

//定义抽烟接口

interface Smoking {

//抽烟的抽象方法

public abstract void smoke();

}


//定义抽象人类

abstract class Person {

//姓名

private String name;

//年龄

private int age;

public Person() {}

public Person(String name,int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

//吃饭();

public abstract void eat();

//睡觉(){}

public void sleep() {

System.out.println("睡觉觉了");

}

}


//具体老师类

class Teacher extends Person {

public Teacher() {}

public Teacher(String name,int age) {

super(name,age);

}

public void eat() {

System.out.println("吃大白菜");

}

}


//具体学生类

class Student extends Person {

public Student() {}

public Student(String name,int age) {

super(name,age);

}

public void eat() {

System.out.println("吃红烧肉");

}

}


//抽烟的老师

class SmokingTeacher extends Teacher implements Smoking {

public SmokingTeacher() {}

public SmokingTeacher(String name,int age) {

super(name,age);

}


public void smoke() {

System.out.println("抽烟的老师");

}

}


//抽烟的学生

class SmokingStudent extends Student implements Smoking {

public SmokingStudent() {}

public SmokingStudent(String name,int age) {

super(name,age);

}


public void smoke() {

System.out.println("抽烟的学生");

}

}


class InterfaceTest2 {

public static void main(String[] args) {

//测试学生

SmokingStudent ss = new SmokingStudent();

ss.setName("林青霞");

ss.setAge(27);

System.out.println(ss.getName()+"---"+ss.getAge());

ss.eat();

ss.sleep();

ss.smoke();

System.out.println("-------------------");

SmokingStudent ss2 = new SmokingStudent("刘意",30);

System.out.println(ss2.getName()+"---"+ss2.getAge());

ss2.eat();

ss2.sleep();

ss2.smoke();

//测试老师留给自己练习

}

}


Java帮帮今日头条号



Java帮帮微信公众号



Java帮帮交流群


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值