首页 > 其他分享 >继承,多态,抽象类,接口

继承,多态,抽象类,接口

时间:2023-09-02 13:01:27浏览次数:29  
标签:void 多态 接口 System class println 抽象类 public out

一,继承

1,概述

-多个类中存在相同的属性和行为时,把这些相同的内容提取到一个独立的类中

其他类就不用在重复定义这些内容,只需要通过extends关键字继承独立的类

class 子类 extends 父类{}

有了继承后,我们就可以在一个已经存在的类的基础上,继续扩展新的成员

class Student{

private String name;

private int age;

public Student() { } public Student(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 void eat(){}

}

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 void eat(){}

}

-我们发现上面2个代码成员变量 name,age一样

get和set方法也一样,吃睡方法也都一样

如果我继续定义工人类,医生类,。。。

他们也具备这些内容

每一次定义这样的类都要把这些重复内容定义一遍

非常麻烦,所以我们要想办法改进

-如何改进?

基本思路,把这些相同的内容提取出来单独存放到一个类中,只存一次

然后让其他类和这个单独的类产生一个关联,让这些类可以具备这些内容

而不用重复定义这些内容

-为了实现这样的效果,java就提供了一种技术: 继承

2,继承如何表示?

-我们把提取出来的类称为父类,基类,超类

-多个有重复内容的类称为,子类,派生类

-继承表示:使用关键字 extends

格式:

class Fu{}

class Zi extends Fu{}

package com.momo.demo;

public class Main {

public static void main(String[] args) {

Student s = new Student();

s.setAge(11);

s.setName("aaa");

System.out.println(s.getName()); System.out.println(s.getAge()); s.eat(); Teacher t = new Teacher("qwe",32); System.out.println(t.getName()); System.out.println(t.getAge()); t.eat(); }

}

//父类

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 void eat(){

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

}

}

//子类

class Student extends Person{

public Student() {

}

public Student(String name, int age) {

super(name,age);

}

}

//子类

class Teacher extends Person{

public Teacher() {

}

public Teacher(String name, int age) {

super(name,age);

}

}

3,好处

-提高了代码的复用性

-提高了代码的维护性

-类和类产生了关系,这个关系是多态的前提

其实这也是个弊端,耦合度增加了

-原则:低耦合,高内聚

4,继承特点

-java只能单继承,不能多继承

一个类只能有一个父类,不能有多个父类

-java可以多层继承(继承体系结构)

class A{}

class B{}

class C extends A{}

class D extends B{}

//class E extends A,B{}

//class E extends A extends B{}

class A{}

class B extends A{}

class C extends B{}

class D extends C{}

package com.momo.demo;

public class Demo2 {

public static void main(String[] args) {

Son s = new Son();

s.fun();

s.show();

}

}

class Ye{

public void show(){

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

}

}

class Ba extends Ye{

public void fun(){

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

}

}

class Son extends Ba{

}

5,继承注意事项

-子类只能继承父类所有非私有的成员

-子类不能继承父类构造方法,但是可以通过super访问父类构造方法

-不要为了部分功能而去继承

-什么时候可以使用继承?

继承体现的是is a 的关系

Person

Student

Teacher

动物

package com.momo.demo;

public class Demo3 {

public static void main(String[] args) {

}

}

class Aaa{

public void show1(){}

public void show2(){}

}

/class Bbb{public void show2(){}public void show3(){}}/

/*

  • 发现bbb中出现了和aaa中一样的方法,所以就想用继承
  • 这样不好,这样不仅有了show2,还多了show1,可以这个show1并不是我们想要的
  • */

class Bbb extends Aaa{

public void show3(){}

}

package com.momo.demo;

public class Demo4 {

public static void main(String[] args) {

Sonn s = new Sonn();

s.fun();

s.show();

//s.method();找不到符号

}

}

class Fu{

private int a = 5;

public int b = 6;

private void method(){ System.out.println(a); System.out.println(b); } public void show(){ System.out.println(a); System.out.println(b); method(); }

}

class Sonn extends Fu{

public void fun(){

// System.out.println(a); a 在 com.momo.demo.Fu 中是 private 访问控制

System.out.println(b);

}

}

6,继承后成员变量的关系

-子类成员变量名和父类成员变量名不一样,这个简单

-子类成员变量名和父类成员变量名一样,在子类方法中访问的时候访问顺序是?

在子类方法中找,有就用

在子类成员位置找,有就用

在父类的成员位置找,有就用

如果还找不到,就报错(没有考虑父类的父类)

package com.momo.demo;

public class Demo5 {

public static void main(String[] args) {

Zi z = new Zi();

System.out.println(z.a);

System.out.println(z.b);

z.show();

}

}

class Father{

// public int a = 5;

public void fun(){

int a = 456;

}

}

class Zi extends Father{

// public int a = 555;

public int b = 6;

public void show(){ // int a = 55555; System.out.println(a); }

}

7,super关键字

-super的用法和this很像

this表示本类对象的引用

super表示父类对象的引用

-他们都有如下用法

访问成员变量

this.成员变量

super.成员变量

访问构造方法

this(...)

super(...)

访问成员方法

this.成员方法(...)

super.成员方法(...)

package com.momo.demo;

/*

  • 要访问子类成员a?
  • 要访问父类成员a?
  • */

public class Demo6 {

public static void main(String[] args) {

S s = new S();

s.show();

}

}

class F{

public int a = 5;

}

class S extends F{

public int a = 6;

public void show(){

int a = 7;

System.out.println(a);

System.out.println(this.a);

System.out.println(super.a);

}

}

8,继承后构造方法的关系

-子类中的所有构造方法默认都会访问父类的无参构造。为什么?

因为子类会继承父类中的数据,可能还要使用父类中的数据

所以子类初始化完成之前,一定要先完成父类数据的初始化

子类继承父类之后,子类中的所有构造方法第一句都是

super()

package com.momo.demo;

/*

  • 要访问子类成员a?
  • 要访问父类成员a?
  • */

public class Demo6 {

public static void main(String[] args) {

S s = new S();

//s.show();

S s2 = new S(123);

}

}

class F{

public F(){

System.out.println("父无参");

}

public F(int i){

System.out.println("父带参");

}

public int a = 5;

}

class S extends F{

public S(){

// super();

System.out.println("ZI无参");

}

public S(int i){

super();

System.out.println("ZI带参");

}

public int a = 6;

public void show(){

int a = 7;

System.out.println(a);

System.out.println(this.a);

System.out.println(super.a);

}

}

-如果父类中没有无参构造怎么办?

子类为什么要访问父类的构造方法?是为了完成父类数据初始化来供子类使用

既然没有无参构造,肯定有带参构造,那么就可以使用带参构造来显示完成

父类数据初始化操作。super(...)

通过super显示调用父类的带参构造

package com.momo.demo;

/*

  • 注意:super或this必须是第一条语句
  • */

public class Demo6 {

public static void main(String[] args) {

S s = new S();

//s.show();

S s2 = new S(123);

}

}

class F{

/* public F(){

System.out.println("父无参");

}*/

public F(int i){

System.out.println("父带参");

}

public int a = 5;

}

class S extends F{

public S(){

// super();

//super(123);

this(123);

System.out.println("ZI无参");

}

public S(int i){

super(123);

// super();

System.out.println("ZI带参");

}

public int a = 6;

public void show(){

int a = 7;

System.out.println(a);

System.out.println(this.a);

System.out.println(super.a);

}

}

package com.momo.demo;

/*

  • 子父类的初始化顺序
  • 代码块的执行顺序和次数
  • */

public class Demo7 {

public static void main(String[] args) {

Y y = new Y();

// y.show();

}

}

class X{

static{

System.out.println("帅哥");

}

{

System.out.println("美女");

}

public int a = 5;

public X(){

System.out.println("我");

}

}

class Y extends X{

static{

System.out.println("大长腿");

}

{

System.out.println("萝莉");//帅哥,大长腿,美女,我,萝莉,是,

}

public int a = 6;

public Y(){

System.out.println("是");

}

public void show(){

int a = 7;

System.out.println(a);

System.out.println(this.a);

System.out.println(super.a);

System.out.println("屌丝");

}

}

package com.momo.demo;

/*

  • 子父类的初始化顺序
  • 一个类的初始化过程
  • */

public class Demo8 {

public static void main(String[] args) {

c c = new c();

}

}

class a{

b b = new b();

a(){

System.out.println("a");

}

}

class b{

b(){

System.out.println("b");

}

}

class c extends a{

b b = new b();

c(){

System.out.println("c");

}

}

9,继承后成员方法的关系

-子类中的方法和父类中的方法不一样这个简单

-子类中的方法和父类中的方法一样,通过子类对象调用的时候

先在子类中找,有就用

在父类中找,有就用

还没有,就报错(没有考虑父类的父类)

package com.momo.demo;

public class Demo9 {

public static void main(String[] args) {

Zii z = new Zii();

z.fun();

z.show();

// z.aaa();

}

}

class Fa{

public void show(){

System.out.println("fushow");

}

}

class Zii extends Fa{

public void fun(){

System.out.println("zifun");

}

/* public void show(){

System.out.println("zishow");

}*/

}

10,方法重写

-上面案例中子类中出现了和父类中一摸一样的方法声明

的这种现象我们称为方法的重写(复写,覆盖)

-使用特点:

方法名不同,调用对应的

方法名相同,重写之后用的是子类自己的

-方法重写的应用

子类需要父类的功能,但是功能的主题子类有自己特有的内容的时候

我们就可以重写父类方法

这样既可以延续父类的功能,又可以定义自己特有的内容。

package com.momo.demo;

/*

  • 最早的手机只能打电话
  • 随着科技不断进步,现在已经研究除了很多新手机
  • 不仅仅可以打电话,还有很多其他功能
  • 在打电话的同时还可以干什么事情(显示通话时长,显示来电归属地信息...)

  • 我们按照分析定义了新手机类,重新编写了打电话方法,添加了功能
  • 但是不好,因为新手机是不是手机? 是手机,新手机应该继承手机类
  • 而且打电话的功能是手机本身就具备的基本功能
  • 这个功能在新手机中不用在重复编写,但是不编写这个代码,又大不了电话了。
  • 最终还是要加上这个功能,由于它继承了手机类,所以我们可以直接使用父类的功能即可
  • 通过super关键字调用父类已经实现过的功能,再去添加自己特有内容即可
  • / public class Demo10 { public static void main(String[] args) { NewPhone np = new NewPhone(); np.call("默默"); } } /
  • 定义一个手机类
  • */

class Phone{

public void call(String name){

//可能真正完成这个功能需要500行代码

System.out.println("给"+name+"打电话");

}

}

//新手机

class NewPhone extends Phone{

public void call(String name){

//System.out.println("给"+name+"打电话");

super.call(name);

System.out.println("通话时长");

System.out.println("归属地信息");

}

//很多其他功能

}

11,方法重写的注意事项

-父类中私有的方法不能被重写

私有的无法继承,谈不上重写

-子类重写父类方法时,访问权限不能更低,最好一致

-父类中的静态方法,子类也必须使用静态方法来重写

注意:这个本质上不是重写,只是现象上如此

package com.momo.demo2;

public class Demo1 {

public static void main(String[] args) {

Son s = new Son();

s.show();

s.fun();

}

}

class Father{

/* private void show(){

System.out.println("privatefushow");

}*/

/* public void show(){

System.out.println("fushow");

}*/

void show(){

System.out.println("fushow");

}

public static void fun(){

System.out.println("fustatic");

}

}

class Son extends Father{

/* private void show(){

System.out.println("privatezishow");

}//

public static void main(String[] args) {

Son s = new Son();

s.show();

}*/

//正在尝试分配更低的访问权限; 以前为public

/void show(){System.out.println("zishow");}/

public void show(){ System.out.println("zishow"); } // 被覆盖的方法为static /*public void fun(){ System.out.println("zistatic"); }*/ public static void fun(){ System.out.println("zistatic"); }

}

12,相关问题

-方法重写和重载的区别

-方法重载可以改变返回值类型码?重载跟返回值类型无关(两同一不同,同一类同一方法名,不同参数)

-this和super的区别以及用法

13,继承练习(标准代码)

-先分析在实现

分析:从具体到抽象的过程

实现:从抽象到具体的过程

-老师和学生案例

-猫和狗案例

分析:从具体到抽象的过程

猫:

成员变量:name,age,color

构造方法:无参,带参

成员方法:get和set,eat,sleep,抓老鼠

狗:

成员变量:name,age,color

构造方法:无参,带参

成员方法:get和set,eat,sleep,看门

共性内容:

成员变量:name,age,color

构造方法:无参,带参

成员方法:get和set,eat,sleep

提取一个父类---动物类

实现:从抽象到具体的过程

动物类:

成员变量:name,age,color

构造方法:无参,带参

成员方法:get和set,eat,sleep

猫继承动物:

构造方法:无参,带参

成员方法:抓老鼠

狗继承动物:

构造方法:无参,带参

成员方法:看门

测试:

无参+set方法

带参

//父类

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 void eat(){

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

}

}

//子类

class Student extends Person{

public Student() {

}

public Student(String name, int age) {

super(name,age);

}

public void study(){}

}

//子类

class Teacher extends Person{

public Teacher() {

}

public Teacher(String name, int age) {

super(name,age);

}

public void teach(){}

}

day7,

7,final关键字

-继承中有个现象叫重写, 父类的功能就会被子类的覆盖掉。

有些时候不想让子类重写,为了实现这样的效果,java就带着final关键字来了。

-final最终的意思

可以修饰类,方法,变量

package com.momo.demo;

public class Demo8 {

public static void main(String[] args) {

Bb b = new Bb();

b.show();

}

}

class Aa{

public final void show(){

System.out.println("aaa");

}

}

class Bb extends Aa{

// 被覆盖的方法为final

/public void show(){System.out.println("bbb");}/

}

-修饰类:不能被继承

-修饰方法:方法不能被重写

-修饰变量:变成常量(自定义常量)

package com.momo.demo;

public class Demo8 {

public static void main(String[] args) {

/* Bb b = new Bb();

b.show();*/

int a = 5; a = 55; System.out.println(a); // final int b = 6; // b = 66;法为最终变量b分配值 final int b; b = 6; System.out.println(b); }

}

final class Aa{

public final void show(){

System.out.println("aaa");

}

}

//无法从最终com.momo.demo.Aa进行继承

/class Bb extends Aa{// 被覆盖的方法为final//public void show(){System.out.println("bbb");}//}/

8,相关问题

-final修饰变量的问题

基本类型:值不能变

引用类型:地址值不能变

package com.momo.demo;

public class Demo9 {

public static void main(String[] args) {

final int a = 5;

System.out.println(a);

final Cat c = new Cat(); System.out.println(c); // c = new Cat();无法为最终变量c分配值 // System.out.println(c); c.age = 22; System.out.println(c.age); }

}

class Cat{

int age = 11;

}

-final修饰成员变量的初始化时机(非静态的)

在对象构造完成之前即可

package com.momo.demo;

public class Demo9 {

public static void main(String[] args) {

final int a = 5;

System.out.println(a);

final Cat c = new Cat(); System.out.println(c); // c = new Cat();无法为最终变量c分配值 // System.out.println(c); //c.age = 22; System.out.println(c.age); // c.age = 33; 无法为最终变量age分配值 System.out.println(c.age); }

}

class Cat{ final int age; Cat(){ age = 22; // age = 22; } }

一,多态

1,概述

-同一事物在不同时刻表现出来的不同状态

-父类引用指向子类对象

人类

老师类

学生类

老师类 老师 = new 老师类(); 学生类 学生 = new 学生类(); //多态 人类 人 = new 老师类(); 人类 人 = new 学生类();

2,前提和体现

-前提:有继承关系

有方法重写(不重写没有意义了)

-体现:父类引用指向子类对象

package com.momo.demo;

public class Demo9 {

public static void main(String[] args) {

/* Cat c = new Cat();

c.eat();

Dog d = new Dog(); d.eat();*/ //多态 Animal a = new Cat(); a.eat(); a = new Dog(); a.eat(); }

}

class Animal{

public void eat(){

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

}

}

class Cat extends Animal{

}

class Dog extends Animal{

}

3,多态下成员的访问特点

-成员变量

编译看父类,运行看父类

-构造方法

创建子类对象,访问父类构造。

-成员方法

编译看父类,运行看子类

-静态方法

编译看父类,运行也看父类

(静态和类相关)

package com.momo.test;

public class Demo1 {

public static void main(String[] args) {

/* Zi z = new Zi();

System.out.println(z.a);

System.out.println(z.b);

z.show();

z.method();

z.fun();*/

//多态 Fu f = new Zi(); System.out.println(f.a); // System.out.println(f.b);//找不到符号 f.show(); // f.method();找不到符号 f.fun(); }

}

class Fu{

Fu(){

System.out.println("aa");

}

public int a = 5;

public void show(){ System.out.println("fushwo"); } public static void fun(){ System.out.println("fustaticfun"); }

}

class Zi extends Fu{

Zi(){

System.out.println("bbb");

}

public int a = 55;

public int b = 66;

@Override public void show() { System.out.println("zishow"); } public void method(){ System.out.println("zimethod"); } public static void fun(){ System.out.println("zistaticfun"); }

}

4,多态的好处和弊端

-好处:

提高了复用性(继承)

提高了维护性(继承)

提高了扩展性(多态)

package com.momo.test;

public class Demo2 {

public static void main(String[] args) {

//我喜欢猫

Cat c1 = new Cat();

/* c1.eat();

c1.sleep();/// useCat(c1);// AnimalTools.useCat(c1);AnimalTools.useAnimal(c1);//我很喜欢猫,又养一只Cat c2 = new Cat();// AnimalTools.useCat(c2);// useCat(c2);/

c2.sleep();/AnimalTools.useAnimal(c2);//我非常喜欢猫,再养一只Cat c3 = new Cat();// AnimalTools.useCat(c3);/

c3.sleep();/// useCat(c3);AnimalTools.useAnimal(c3);//..../

* 问题:我养了很多猫,每次都创建对象 这个没有问题

* 问题在于调用方法,每次调用的都是一样的方法,只是对象名不一样。

* 所以需要改进。如何改进?

* 可以编写一个方法,通过这个方法去调用其他所有方法,参数就不不同的对象

*

* 有了方法后,就可以改进调用方法,调用简单了。

* */

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

//我喜欢狗

Dog d1 = new Dog();

// AnimalTools.useDog(d1);

/*d1.eat();

d1.sleep();

/AnimalTools.useAnimal(d1);// useDog(d1);//我很喜欢狗Dog d2 = new Dog();//AnimalTools.useDog(d2);/

d2.sleep();*/

// useDog(d2);

AnimalTools.useAnimal(d2);

//出现和上面一样的问题,应该继续编写方法来改进调用方式

/* //使用狗对象所有方法的方法

public static void useDog(Dog d){

d.eat();

d.sleep();

}

//使用猫对象所有方法的方法

public static void useCat(Cat c){

c.eat();

c.sleep();

}//

* 根据分析,我们写了这2个方法,目前时再测试类中写的,合适码?

* 不合适。 应该写在哪里?

* 目前来说不管写在测试类,动物类,猫类,狗类 都不合适

* 因为这两个方法不是动物本身就具备的功能。

* 而是我们为了方便使用创建的快捷方法,是一种方便使用的工具。

*

* 所以我们应该额外定义一个工具类,来存储这些方法。

* 根据分析进行改进,改进后的调用方式就变了。

* /// AnimalTools.useDog(d1);// AnimalTools.useDog(d2);/

* 如果我后面又喜欢 ?? ,??,??,??,.... 这些动物

* 定义对应的类,继承动物类,重写对应的方法 这些都没有问题

* 每次为了方便使用还要再工具类中添加对应的use方法, 这个有问题

* 因为一旦出错,就会导致整个工具类无法使用。

* */

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

Pig p = new Pig();

// AnimalTools.usePig(p);

AnimalTools.useAnimal(p);

}

}

class Animal{

String name;

String color;

String gender;

int age;

public void eat(){ System.out.println("吃"); } public void sleep(){ System.out.println("睡"); } public void show(){ System.out.println(name+"---"+age+"---"+color+"---"+gender); }

}

class Cat extends Animal{

public void eat(){

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

}

public void sleep(){

System.out.println("猫蜷着睡");

}

}

class Dog 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 AnimalTools{private AnimalTools(){}//使用狗对象所有方法的方法/

d.eat();

d.sleep();

}

//使用猫对象所有方法的方法

public static void useCat(Cat c){

c.eat();

c.sleep();

}

public static void usePig(Pig p){

//int a = "a";

p.eat();

p.sleep();

}*/

public static void useAnimal(Animal a){

//父类引用指向子类对象,,多态。。。

//Animal a = new Dog()

//Animal a = new Cat()

//Animal a = new Pig()

//Animal a = new She()

a.eat();

a.sleep();

}

}

-弊端:

多态情况下无法访问子类特有内容(弊端)

我就要访问怎么办?

创建子类对象

把父类的引用强转成子类的引用(向下转型)

向上转型

Fu f = new Zi();

向下转型

Zi z = (Zi)f;

注意:f必须是能够转换成Zi的

ClassCastException 类型转换异常

Animal a = new Cat(); Cat c = (Cat)a; c.eat(); a = new Dog(); //Dog d = (Dog)a; //ClassCastException 类型转换异常 // Cat cc = (Cat)a; // cc.eat(); // d.eat();

package com.momo.test;

public class Demo3 {

public static void main(String[] args) {

Father f = new Son();

f.show();

// f.fun();找不到符号

//向下转型 Son s = (Son)f; s.fun(); s.show(); }

}

class Father{

public void show(){

System.out.println("fushow");

}

}

class Son extends Father{

public void show(){

System.out.println("zishow");

}

public void fun(){ System.out.println("zifun"); }

}

5,多态练习(多态标准写法)

-老师和学生

-猫狗案例

package com.momo.test;

public class Demo4 {

public static void main(String[] args) {

/* A a = new B();

a.show();*/

B b = new C(); b.show(); }

}

class A{

public void show(){

show2();

}

public void show2(){

System.out.println("高");

}

}

class B extends A{

public void show() {

super.show();

}

@Override

public void show2() {

System.out.println("富");

}

}

class C extends B{

@Override

public void show() {

super.show();

}

@Override public void show2() { System.out.println("帅"); }

}

二,抽象类

1,概述

-前面案例提取出来的父类,不是一个具体的事物,不应该new

所以我们应该声明成抽象类。

-父类中的方法不应该给出具体的实现,也应该声明为抽象方法

2,特点

-抽象类,抽象方法都要用 abstract来修饰。

-抽象类中不一定有抽象方法,但是有抽象方法的类必须是抽象类

-抽象类本身不能实例化,但是可以依赖多态实现实例化---抽象类多态

通过具体的子类实现实例化

-抽象类的子类:

可以是抽象类,可以不重写抽象方法

也可以是具体类,必须重写父类中的所有抽象方法

package com.momo.test;

public class Demo5 {

public static void main(String[] args) {

//Catt s = new Catt();

// s.eat();

//抽象类多态 Anima p = new Dogg(); p.eat(); /* * 这个有问题, 我创建了一个动物对象 ,动物?到底是什么动物? * Animal a = new Animal(); * 动物?到底是什么动物? 不应该new 它不是一个具体的事物 * 它是一个抽象的事物,这个类应该是一个抽象类,抽象类也要用 abstract来修饰 * 只有具体的猫或这狗才是具体的事物。 * 不同的动物吃的不一样, 所以动物类中的eat方法不应该给出具体的实现 * 应该强制要求子类必须重写 ,如何实现? * java带着关键字 abstract 来了。 * 一个没有具体实现的方法(没有{方法体}方法)我们应该定义为抽象方法, 抽象方法要用abstract 修饰 * 一个类中如果有了抽象方法,这个类也应该定义为抽象类。 * */ // Anima pp = new Anima(); com.momo.test.Anima是抽象的; 无法实例化 //pp.eat(); }

}

abstract class Anima{

/* public void eat(){

System.out.println("吃");

}*/

//没有方法体的方法要定义为抽象方法

public abstract void eat();

}

abstract class Catt extends Anima{

/* public void eat(){

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

}*/

}

class Dogg extends Anima{

public void eat(){

System.out.println("狗吃骨头");

}

}

3,抽象类的成员特点

-成员变量

可以是变量,也可以是常量

-构造方法

有,但是不能造对象

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

-成员方法

抽象的,要求子类必须做的

非抽象的,给子类继承的,提高复用性

package com.momo.test;

public class Demo6 {

public static void main(String[] args) {

Animall aa = new Tiger();

System.out.println(aa.a);

aa.a = 55;

System.out.println(aa.a);

System.out.println(aa.b);

aa.fun();

aa.show();

// Animall a = new Animall();com.momo.test.Animall是抽象的; 无法实例化 }

}

abstract class Animall{

int a = 5;

final int b = 6;

Animall(){ System.out.println("wucan"); } Animall(int a){ System.out.println("daican"); } abstract void show(); public void fun(){ System.out.println("aaa"); }

}

class Tiger extends Animall{

@Override void show() { System.out.println("dfdfd"); }

}

4,抽象类练习

-猫狗案例

分析:从具体到抽象

具体事物:猫和狗

猫:

成员变量:姓名,年龄,颜色。。。

构造方法:无参,带参

成员方法:get,set,eat,sleep, catchMouse。show。。。

狗:

成员变量:姓名,年龄,颜色。。。

构造方法:无参,带参

成员方法:get,set,eat,sleep, lookDoor。show。。。

有共性内容,提取父类动物类,不同的动物吃的不一样,吃应该是抽象的, 那么这个类也应该是抽象类。 抽象动物类: 成员变量:姓名,年龄,颜色。。。 构造方法:无参,带参 成员方法:get,set,abstract eat(),sleep, show。。。 实现:从抽象到具体 定义抽象动物类 成员变量:姓名,年龄,颜色。。。 构造方法:无参,带参 成员方法:get,set,abstract eat(),sleep, show。。。 狗类继承动物类 成员变量: 构造方法:无参,带参 成员方法:重写eat ,添加 lookDoor。 猫类继承动物类 成员变量: 构造方法:无参,带参 成员方法:重写eat ,添加 catchMouse 测试类测试: 具体类测试: 无参+set 带参 多态测试:向下转型 无参+set 带参

-老师和学生案例

-我们要设计一个员工系统,需要对员工类进行设计,

员工包含3个属性:工号,姓名,工资

经理也是员工,除了上面3个属性之外,还多了一个奖金属性

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

并测试。。。

5,抽象类的相关问题

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

-抽象关键字不能和哪些关键字共存?

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

final 冲突 非法的修饰符组合: abstract和final

static 冲突 非法的修饰符组合: abstract和static


三,接口

1,概述

-前面的猫狗案例,猫狗除了吃睡玩,然后就是看门,抓老鼠。

现在社会中有中职业驯兽师,可以训练出会钻火圈的猫,会计算的狗,....

这些额外的功能不是动物本身就具备的,是训练出来的,所以这些功能

不能定义到动物类中,所以为了体现事物的扩展性,java就提供了接口

来定义这些扩展功能,再接口中这些功能不能给出具体的实现(不同动物训练方式不一样)

将来哪些具体的动物被训练了,这部分动物去实现接口中的这些功能即可

2,特点

-定义接口使用关键字 interface

格式: interface 接口名{}

-实现接口用 implements 关键字

格式:class 类名 implements 接口名{}

-接口本身不能实例化

但是可以依赖具体的实现类实现实例化---接口多态

具体类多态:几乎不用

抽象类多态:常用

接口多态:常用

-接口的实现类

可以是抽象类,可以不重写, 意义不大

可以是具体类,必须重写所有抽象方法

package com.momo.test;

public class Demo7 {

public static void main(String[] args) {

//com.momo.test.AniamlInterface是抽象的; 无法实例化

//AniamlInterface ai = new AniamlInterface();

//接口多态

AniamlInterface ai = new Snake();

ai.fireCircle();

ai.fun();

//ai.show();找不到符号

Snake ss = (Snake) ai; ss.show(); }

}

interface AniamlInterface{

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

/* public void fireCircle(){

System.out.println("钻火圈");

}*/

//接口中的方法有默认修饰符 public abstract 但是建议自己写上 void fireCircle(); public abstract void fun();

}

abstract class Lion implements AniamlInterface{

}

class Snake implements AniamlInterface{

@Override public void fireCircle() { System.out.println("bbb"); } @Override public void fun() { System.out.println("aaa"); } public void show(){ System.out.println("adf"); }

}

3,接口的成员

-成员变量:

只能是静态常量,有默认修饰符 public static final

-构造方法:

没有构造方法,接口用来定义扩展功能的

-成员方法:

有默认修饰符 public abstract

只能是抽象方法(针对我们自己定义的普通方法)

可以有默认的非抽象方法

可以有静态的非抽象方法

package com.momo.test;

public class Demo8 {

public static void main(String[] args) {

/* Inter i = new InterImp();

System.out.println(i.a);

// i.a = 55;无法为最终变量a分配值

System.out.println(i.a);

System.out.println(i.b);*/

//说明了 其实还有一个默认修饰符 static System.out.println(Inter.a); System.out.println(Inter.b); }

}

interface Inter{

int a = 5;//实际上不是一个变量,默认修饰符 final

final int b = 6;

public static final int c = 7;

//接口中的成员变量有默认修饰符 public static final ,接口中的成员变量只能是静态的常量

}

class InterImp implements Inter{

}

public class Demo7 {

public static void main(String[] args) {

AniamlInterface ai = new Snake();

ai.aaa();

// ai.bbb();

AniamlInterface.bbb(); }

}

interface AniamlInterface{

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

/* public void fireCircle(){

System.out.println("钻火圈");

}*/

//接口中的方法有默认修饰符 public abstract 但是建议自己写上 void fireCircle(); public abstract void fun(); public default void aaa(){ System.out.println("接口默认方法"); } public static void bbb(){ System.out.println("接口静态方法"); }

}

class Snake implements AniamlInterface{

@Override public void fireCircle() { System.out.println("bbb"); } @Override public void fun() { System.out.println("aaa"); } public void show(){ System.out.println("adf"); }

}:

标签:void,多态,接口,System,class,println,抽象类,public,out
From: https://blog.51cto.com/u_16230968/7332046

相关文章

  • android面试题:谈谈对Java中多态的理解
     Java中的多态是面向对象编程的一个重要特征,它允许同一个类型的对象在不同的情况下表现出不同的行为。多态是Java语言中实现代码复用、提高代码可维护性和可扩展性的重要手段。 多态的实现基于两个核心概念:继承和方法重写。在Java中,子类可以继承父类的方法,并且可以重写(覆......
  • 10-1 以太网接口类型(Access,Trunk)抓包理解
    Access接口类型抓包理解Access的收发规则如下ACCESS接口常用来连接终用户PC,服务器,等终端设备的接口,ACCESS接口接受和发送的数据大都为没有VlanTag的Access接口接受到没有带VLANTag的数据帧加上VlanTagAccess接口如果收到带有VLANtag的数据帧,VlanTag与PVID相同则接受,不......
  • 华为交换机接口类型汇总
    接入链路和干道链路如何处理标签!   华为设备默认所有接口的缺省标签为1   只要接口配置有缺省标签,就会对标签做处理交换机链路分为干道链路和接入链路.    接入链路:一条链路一端为二层接口,另外一端为非二层接口.    干道链路:一条链路的两端均为二层接口. ......
  • 京东API接口解析,实现按关键字搜索商品
    京东开放平台提供了丰富的API接口,用于查询商品、用户、订单等信息。以下是一个基本的示例,解析并实现按关键字搜索商品的API接口。需要访问京东开放平台并注册一个开发者账号。注册完成后,你需要创建一个应用并获取到API的权限。在获取到API权限后,你可以在开发者的控制台中找到API的......
  • flask + gevent + multiprocess + wsgi实现高并发接口
    Flask+多进程+协程了。8核虚拟机最高QPS高达1W5。使用的时候务必注意一下“”“进程“”“安全就行了。参考代码如下,Flaskgevent多进程WSGI(非gunicorn)#coding:utf-8#codebyhttps://cpp.la,2020-04-20#flask+gevent+multiprocess+wsgifromflaskimpo......
  • C++读取调用接口返回的json数据
    1、引入头文件#include<boost/property_tree/ptree.hpp>#include<boost/property_tree/json_parser.hpp>ViewCode2、读取json数据方法,http请求中的chunked传输数据会返回数据的长度,在最后一个chunked中其头部长度定为0//读取json文件{"name":"zhangsan","age":25}......
  • SpringBoot使用protobuf格式的接口方式
    建立SpringBoot项目,pom.xml内容如下:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="......
  • C#中接口的实例化
    一、接口回调就是继承中的向上转型。父类FL=new子类();只不过这里的父类就是interface接口。(个人认为这里不管是class的override还是interface的重写,都是一样的用法)可以把实现某一接口类创建的对象的引用赋给该接口声明的接口变量,那么该 接口变量就可以调用被类实现的接口中......
  • TienChin 渠道管理-查看渠道接口
    自定义hasPermission校验规则自定义一个SpringSecurityhasPermission校验规则:在tienchin-framework模块当中进行自定义,新建CustomSecurityExpressionRoot.java自定义hasPermission判断逻辑类:/***@authorBNTang*@version1.0*@description自定义hasPerm......
  • restful规范和django源码写接口
    一、restful规范1、restful规范是什么,如何来的?一种定义WebAPI接口的设计风格,尤其适用于前后端分离的应用模式中的规范RoyFielding的博士论文提出的2、以后写接口,大致都要遵循如下规范-1数据的安全保障-》url链接一般都采用https协议进行传输--》它比http安全......