第十三章 抽象类和接口

1.作业回顾

1,编写一个Person类,包括属性(name、age),有参构造器、方法say(返回自我介绍的字符串)。

2.编写一个Student类,继承Person类,增加sno、score属性,以及有参构造器,在子类中调用父类的构造器。

3.编写一个方法showInfo(返回自我介绍的字符串)。

1.编写一个Person类,包括属性(name、age),有参构造器、方法say(返回自我介绍的字符串)。public class Person {//属性(name、age)private String name;private int 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 Person(String name, int age) {super();this.name = name;this.age = age;}//方法say(返回自我介绍的字符串)public String say() {return "我叫" + name + ",我今年:" + age + "岁了";}
}
//2.编写一个Student类,继承Person类,增加sno、score属性,以及有参构造器,在子类中调用父类的构造器。public class Student extends Person {//增加sno、score属性private int sno;private int score;public int getSno() {return sno;}public void setSno(int sno) {this.sno = sno;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}//有参构造器public Student(String name, int age, int sno, int score) {super(name, age);this.sno = sno;this.score = score;}//3.编写一个方法showInfo(返回自我介绍的字符串)。public String showInfo() {return super.say() + "我的学号是" + sno + "我的分数是" + score;}
}
public class Day128 {//1.编写一个Person类,包括属性(name、age),有参构造器、方法say(返回自我介绍的字符串)。 //2.编写一个Student类,继承Person类,增加sno、score属性,以及有参构造器,在子类中调用父类的构造器。//3.编写一个方法showInfo(返回自我介绍的字符串)。public static void main(String[] args) {Student s = new Student("张三", 20, 20191101, 100);System.out.println(s.showInfo());            }//我叫张三,我今年:20岁了我的学号是20191101我的分数是100
}

2.继承规则二

子类并不会继承超类的private成员,但是子类可以调用超类的public,protected,default方法来访问超类的私有字段。

public class Animal {private String name;public Animal(String name) {super();this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
public class Dog extends Animal{private int age;public Dog(String name, int age) {super(name);this.age = age;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void say() {System.out.println("我叫" + getName() + "我今年" + age + "岁了");}
}
public class Day1302 {public static void main(String[] args) {Dog d = new Dog("小狗1", 10);d.say(); //我叫小狗1我今年10岁了}
}

父类型的变量可以引用子类型的对象

import java.util.Date;class Animal {}class Pet extends Animal {}class Dog extends Pet {}public class Day1303 {public static void main(String[] args) {//超类型的变量可以引用子类型的对象Animal a1 = new Pet();Animal a2 = new Dog();Pet a3 = new Dog();//由于Object类是所有类型的的超类,因此Object类的变量可以引用任何类的实例Object o1 = new Animal();Object o2 = new String();Object o3 = new Date();}
}

java中不支持多继承,即只能继承一个类。但是可以使用继承链。

class Dog extends Animal,Pet { //编译错误}

3.方法重写

子类可以创建和超类拥有同样签名(方法名和参数列表)的方法,这叫做方法重写。

class Animal {public void bark() {System.out.println("不知道");}
}class Cat extends Animal {public void bark() {System.out.println("喵喵喵");}
}public class Day1304 {public static void main(String[] args) {Cat c = new Cat();c.bark();}
}

方法重写的规则

1.子类重写的方法不能比超类有更小的访问权限。

2.被标记为final的方法不能被重写。

3.在重写的方法中可以使用super关键字来调用其超类的方法。

4.重写方法的返回值类型不能比父类的大。

5.子类只能重写它可见的方法。 static成员不考虑继承问题,因此不能被重写。

4.多态

多态是指:执行同一个方法却产生不同的行为。 多态的前提是继承和方法重写。

多态:执行哪个方法看的是引用的对象的类型,而不是变量的类型。

class Animal {public void bark() {System.out.println("不知道");}
}class Dog extends Animal {public void bark() {System.out.println("汪汪汪");}
}class Cat extends Animal {public void bark() {System.out.println("喵喵喵");}
}public class Day1305 {public static void main(String[] args) {//执行同一个方法却产生不同的行为//a1引用的是Animal类型的对象,因此会调用Animal类的bark方法,运行时看对象的类型Animal a1 = new Animal();a1.bark(); //不知道//a2引用的是Dog类型的对象,因此会调用Dog类的bark方法,运行时看对象的类型Animal a2 = new Dog();a2.bark(); //汪汪汪//a3引用的是Cat类型的对象,因此会调用Cat类的bark方法,运行时看对象的类型Animal a3 = new Cat();a3.bark(); //喵喵喵//执行同一个方法却产生不同的行为Animal[] arr = { new Animal(), new Dog(), new Cat()};//调用实际引用的对象的方法arr[0].bark(); //不知道arr[1].bark(); //汪汪汪arr[2].bark(); //喵喵喵}
}
class Animal {public void bark() {System.out.println("不知道");}
}class Dog extends Animal {public void bark() {System.out.println("汪汪汪");}public void run() {System.out.println("run");}
}public class Day1306 {public static void main(String[] args) {// 变量的类型是Animal,对象的类型是DogAnimal a1 = new Dog();// 运行时看对象的类型a1.bark(); // 汪汪汪// 编译时看变量的类型,只能看到Animal类的方法,看不到实际引用对象的方法
//      a1.run(); //编译错误// 变量类型是Animal,它只能调用bark方法,但却不能调用run方法。 // 可以使用强制类型转换将变量a1的变量类型转换为Dog,这样就能调用run方法。Dog a2 = (Dog) a1;a2.run(); // 正确Animal a3 = new Animal(); // 可以使用强制类型转换将a3的变量类型转换为Dog // 但是a3,a4实际引用的是Animal类型的对象,而此对象没有run方法。Dog a4 = (Dog) a3;
//      a4.run(); //运行时错误,没有run方法。编译时通过}
}

5.final修饰符

被final修饰的类不能被继承。

被final修饰的方法不能被重写。 被final修饰的变量不能被修改。

被final修饰的参数不能被修改。

6.抽象类

图形对象都具有某些属性(位置)和方法(moveTo,draw)。

对于所有的图形,这些属性和方法中的一些是相同(位置,moveTo)。draw有些特殊。每个子类的draw方法提供的功能不同。

可以在父类中提供一个draw方法,在 子类中使用方法重写来完成特定的draw方法。

class GraphicObject {// x,y代表图形的位置protected int x;protected int y;public GraphicObject(int x, int y) {super();this.x = x;this.y = y;}// 移动到(x,y)点上void moveTo(int x, int y) {this.x = x;this.y = y;}void shoeLocation() {System.out.println("x = " + x + ", y = " + y);}void draw() {// 不确定要画什么,无法实现}
}class Circle extends GraphicObject {// 构造器Circle(int x, int y) {super(x, y);}public void draw() {System.out.println("画一个圆[" + x + ", " + y + "]");}
}class Rectangle extends GraphicObject {// 构造器Rectangle(int x, int y) {super(x, y);}public void draw() {System.out.println("画一个矩形[" + x + ", " + y + "]");}
}public class Day1307 {public static void main(String[] args) {//GraphicObject应该是抽象的,不应该有具体的对象GraphicObject g = new GraphicObject(0, 0);Circle c = new Circle(0, 2);c.shoeLocation(); //x = 0, y = 2c.draw(); //画一个圆[0, 2]Rectangle r = new Rectangle(5, 6);r.shoeLocation(); //x = 5, y = 6r.draw(); //画一个矩形[5, 6]}
}

上面的例子中存在两个问题: GraphicObject类的draw方法内部是空的,此方法应该在,因为所有图形都应该有draw方法。但是对于基类GraphicObject而言它又不知道如何实现该方法。

GraphicObject(图形)应该是抽象的,不应该有具体的对象。 对于这样的情况可以使用抽象类来实现更加优雅。

//有抽象方法的类必须声明为抽象类,因此声明GraphicObject需要加关键字abstract
//抽象类不能被实例化
abstract class GraphicObject {// x,y代表图形的位置protected int x;protected int y;public GraphicObject(int x, int y) {super();this.x = x;this.y = y;}// 移动到(x,y)点上void moveTo(int x, int y) {this.x = x;this.y = y;}void shoeLocation() {System.out.println("x = " + x + ", y = " + y);}//抽象方法,没有方法体//声明为抽象方法,因为不知道如何实现它//如果父类声明了抽象方法,那么子类就必须要实现它,因此这个方法对所有的子类进行了约束abstract void draw();
}class Circle extends GraphicObject {// 构造器Circle(int x, int y) {super(x, y);}//子类必须实现实现父类的抽象方法,否则这个类必须声明为抽象类public void draw() {System.out.println("画一个圆[" + x + ", " + y + "]");}
}class Rectangle extends GraphicObject {// 构造器Rectangle(int x, int y) {super(x, y);}//子类必须实现实现父类的抽象方法,否则这个类必须声明为抽象类public void draw() {System.out.println("画一个矩形[" + x + ", " + y + "]");}
}public class Day1308 {public static void main(String[] args) {//GraphicObject应该是抽象的,不应该有具体的对象//抽象类不能创建对象
//      GraphicObject g = new GraphicObject(0, 0);Circle c = new Circle(0, 2);c.shoeLocation(); //x = 0, y = 2c.draw(); //画一个圆[0, 2]Rectangle r = new Rectangle(5, 6);r.shoeLocation(); //x = 5, y = 6r.draw(); //画一个矩形[5, 6]}
}

抽象类使用abstract来声明,它可以包含抽象方法,也可以不包含抽象方法。

有时候声明为抽象类,但又不包含抽象方法,仅仅是为了避免被实例化。

抽象类无法被实例化,但是可以被继承。

被abstract修饰的方法称为抽象方法,抽象方法只有声明,没有实现。 如果一个类包含了抽象方法,那它必须被声明为一个抽象类。

如果一个类继承了抽象类,它通常需要实现抽象类的抽象方法,如果没有实现,那这个子类也必须被声明为抽象的。

抽象类天生就是用来被继承的。抽象类实现了它所有子类必须使用的通用方法,这样子类就可以直接继承使用。抽象方法则留给子类根据自己的情况做不同的实现。

定义抽象方法的意义在于:给所有的子类制定一种规则,子类必须要实现抽象方法。

7.接口

接口定义了一个类所能对外提供的功能。接口不能被实例化,只能被实现。 接口可以理解为纯粹的抽象类,接口中的所有方法都是抽象的。 接口描述了一种规则。

//使用关键字interface声明一个接口。接口声明功能。
interface Flyable {//public abstract不是必须的,接口的方法默认是public abstract。//public abstract void fly();void fly();
}//使用关键字implements来实现一个接口。类实现接口中声明的功能。
class Aeroplane implements Flyable {//实现一个接口,必须实现接口中的所有方法,否则此类必须声明为抽象类@Overridepublic void fly() {System.out.println("飞机能飞,飞机使用发动机飞");  }
}class Bird implements Flyable {@Overridepublic void fly() {System.out.println("鸟能飞,鸟使用翅膀飞"); }
}public class Day1309 {public static void main(String[] args) {Bird bird = new Bird();bird.fly(); //鸟能飞,鸟使用翅膀飞  Aeroplane aeroplane = new Aeroplane();aeroplane.fly(); //飞机能飞,飞机使用发动机飞//接口类型的变量可以引用实现了这个接口的类的实例Flyable flyable1 = new Bird(); //Bird实现了Flyable接口,因此这个对象可以被flyable1引用flyable1.fly(); //鸟能飞,鸟使用翅膀飞      多态,会调用其引用对象的fly方法Flyable flyable2 = new Aeroplane();//Aeroplane实现了Flyable接口,因此这个对象可以被flyable2引用flyable2.fly(); //飞机能飞,飞机使用发动机飞       多态,会调用其引用对象的fly方法}
}

接口中的变量总是public static final的,接口中的变量不能声明为private。

interface ExampleInterface1{//接口中的变量默认是public static final。静态常量//value1,value2,value3,value4都是public static finalint value = 10;public int value2 = 15;public static int value3 = 20;public static final int value4 = 25;// private int value5 = 10; //编译错误
}

接口中的方法默认是public abstract的。

interface ExampleInterface1{//默认是public abstractvoid method1();//接口中的方法不允许private
//  private void method6(); //编译错误
}

接口继承

interface ExampleInterface1{//默认是public abstractvoid method1();//接口中的方法不允许private
//  private void method6(); //编译错误
}//子接口
interface SubInterface1 extends ExampleInterface1 {void method2();
}//实现SubInterface
class C1 implements SubInterface1 {@Overridepublic void method1() {}@Overridepublic void method2() {}
}interface ExampleInterface2 {void method2();
}//一个例可以实现多个接口,它必须要实现接口中的所有方法
//可以不实现接口中的所有方法,但是类必须声明为抽象类。
class SampleImpl implements ExampleInterface1, ExampleInterface2 {@Overridepublic void method2() {System.out.println("method2的实现");  }@Overridepublic void method1() {System.out.println("method1的实现");   }
}public class Day1310 {public static void main(String[] args) {//接口类型的变量可以引用实现了这个接口的类的实例ExampleInterface1 i1 = new SampleImpl();i1.method1(); //调用SampleImpl对象的method1方法    //method1的实现
//      i1.method2(); //编译错误,看不到method2方法ExampleInterface2 i2 = new SampleImpl();i2.method2(); //调用SampleImpl对象的method2方法    //method2的实现
//      i1.method1(); //编译错误,看不到method1方法ExampleInterface1 i3 = (ExampleInterface1)i2;i3.method1(); //编译正确,能看到method1方法              //method1的实现
//      i3.method2(); //编译错误,看不到method2方法}
}

8.练习

1,将Frock类声明为抽象类,尺寸在Frock类中定义,在类中声明抽象方法calcArea方法,用来计算衣服的布料面积。编写Shirt类继承Frock类,实现 calcArea方法,用来计算衬衣所需的布料面积(尺寸 * 1.3)。编写Coat类继承Frock类,实现 calcArea方法,用来计算外套所需的布料面积(尺寸*1.5)。编写Test类,测试calcArea方法。

稳稳当当学java之抽象类和接口(11)相关推荐

  1. Java中抽象类和接口在概念、语法和应用上的区别和关系

    2019独角兽企业重金招聘Python工程师标准>>> 春招开始了,盆友们都忙着准备笔试.准备面试,复习学过的知识点,当然我也不例外,在这里祝每一个"有心人"心想 ...

  2. 【零基础学Java】—笔记本USB接口案例(二十八)

    [零基础学Java]-笔记本USB接口案例(二十八) 一.笔记本电脑 笔记本电脑(laptop)通常具备使用USB设备的功能,在生产时,笔记本都预留了可以插入USB设备的USB接口,但具体什么是USB ...

  3. Java基础学习第十二讲:Java面向对象---抽象类和接口

    Java面向对象-抽象类和接口 一.抽象类 抽象的定义: 我们在日常生活中,经常通过总结一些事物的共性来对事物进行分类,这种共性可能是一些相同的属性,也可能是一些相同的动作.通过总结,我们能够清晰的划 ...

  4. 关于Java中抽象类和接口的一点思索

    Java中抽象类和接口的一点思索 成员方法上的区别: 1. java中的抽象类可以提供成员方法的实现细节,抽象方法只能是被public和protected来修饰 配合abstract关键字,子类需要实 ...

  5. Java中抽象类和接口

    一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的实现.抽象方法的声明格式为: 1 abstract void fun(); 抽象方法必须用abst ...

  6. 【JAVA】 抽象类和接口

    抽象类和抽象方法 抽象方法只有声明没有方法体,其语法如下: abstract void f() 含有抽象方法的类叫抽象类,要被abstract修饰 抽象类中可以没有抽象方法 抽象类不能新建对象 如果继 ...

  7. java学习--抽象类与接口

    一.抽象 在使用抽象类时需要注意几点: 1.抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可. 2.抽象方法必须由子类来进行重写. 3.只要包含一个抽象方法的抽象类,该方 ...

  8. java中抽象类和接口的作用与区别

    抽象类与接口的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract ...

  9. 详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

最新文章

  1. jquery获取元素的值,获取当前对象的父对象等等
  2. 一个简单遮罩弹窗效果
  3. 计算机考试一年有肌肉,阅卷老师最想看到什么样的字体?电脑阅卷时代,这种字体很吃香...
  4. MySQL验证索引提升查询效率
  5. redis创建集群报错can‘t connect to node 192.168.163.203
  6. c语言中二维数组的结构体,怎么才能把结构体里面的二维数组打印出来?
  7. java 关键字 sizeof_Java 基本数据类型 sizeof 功能
  8. 系统文件-- lsof
  9. 7 php 内存泄漏_APP内存优化之内存泄漏
  10. [Oracle整理]树形查询(start with connect by)
  11. 全链路跟踪对比,skywalking、zipkin等
  12. 视觉特效·AI视频抠图·换脸
  13. java程序员专业技能_java程序员简历专业技能怎么写
  14. Python(应用) — Tesseract图片文字识别(一)
  15. treetable怎么带参数_jQuery.treetable使用及异步加载
  16. 关闭445端口的方法
  17. word文档通配符换行_Word指定位置批量插入表格,别人花一天搞不出来,我只用了10秒...
  18. java熟人_英语中对各种不同程度关系的朋友是怎么表示的(就像汉语里有泛泛之交、熟人、朋友、死党之类的)?...
  19. 把自己曾经写的一个客户间聊天的程序与大家分享(2)
  20. tabindex的微妙使用

热门文章

  1. canvas文字换行处理
  2. oracle循环怎么写,oracle存储过程循环怎么写
  3. 2022年最新中国科学院期刊分区表变化 | 生物类、医学类
  4. 基于荔枝派Nano学习Buildroot的构建过程
  5. 四小时学习opencv+qt系列(第六天)
  6. 微信小程序之蓝牙开发虚拟摇杆
  7. 计算机和打印机是全双工吗,全双工模式
  8. 收集的一些读之有意的话
  9. 云服务器搭建k8s集群的巨坑,node间网络不通问题
  10. 西门子S7-1200系列PLC输入/输出接线