稳稳当当学java之抽象类和接口(11)
第十三章 抽象类和接口
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)相关推荐
- Java中抽象类和接口在概念、语法和应用上的区别和关系
2019独角兽企业重金招聘Python工程师标准>>> 春招开始了,盆友们都忙着准备笔试.准备面试,复习学过的知识点,当然我也不例外,在这里祝每一个"有心人"心想 ...
- 【零基础学Java】—笔记本USB接口案例(二十八)
[零基础学Java]-笔记本USB接口案例(二十八) 一.笔记本电脑 笔记本电脑(laptop)通常具备使用USB设备的功能,在生产时,笔记本都预留了可以插入USB设备的USB接口,但具体什么是USB ...
- Java基础学习第十二讲:Java面向对象---抽象类和接口
Java面向对象-抽象类和接口 一.抽象类 抽象的定义: 我们在日常生活中,经常通过总结一些事物的共性来对事物进行分类,这种共性可能是一些相同的属性,也可能是一些相同的动作.通过总结,我们能够清晰的划 ...
- 关于Java中抽象类和接口的一点思索
Java中抽象类和接口的一点思索 成员方法上的区别: 1. java中的抽象类可以提供成员方法的实现细节,抽象方法只能是被public和protected来修饰 配合abstract关键字,子类需要实 ...
- Java中抽象类和接口
一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的实现.抽象方法的声明格式为: 1 abstract void fun(); 抽象方法必须用abst ...
- 【JAVA】 抽象类和接口
抽象类和抽象方法 抽象方法只有声明没有方法体,其语法如下: abstract void f() 含有抽象方法的类叫抽象类,要被abstract修饰 抽象类中可以没有抽象方法 抽象类不能新建对象 如果继 ...
- java学习--抽象类与接口
一.抽象 在使用抽象类时需要注意几点: 1.抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可. 2.抽象方法必须由子类来进行重写. 3.只要包含一个抽象方法的抽象类,该方 ...
- java中抽象类和接口的作用与区别
抽象类与接口的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract ...
- 详细解析Java中抽象类和接口的区别
在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...
最新文章
- jquery获取元素的值,获取当前对象的父对象等等
- 一个简单遮罩弹窗效果
- 计算机考试一年有肌肉,阅卷老师最想看到什么样的字体?电脑阅卷时代,这种字体很吃香...
- MySQL验证索引提升查询效率
- redis创建集群报错can‘t connect to node 192.168.163.203
- c语言中二维数组的结构体,怎么才能把结构体里面的二维数组打印出来?
- java 关键字 sizeof_Java 基本数据类型 sizeof 功能
- 系统文件-- lsof
- 7 php 内存泄漏_APP内存优化之内存泄漏
- [Oracle整理]树形查询(start with connect by)
- 全链路跟踪对比,skywalking、zipkin等
- 视觉特效·AI视频抠图·换脸
- java程序员专业技能_java程序员简历专业技能怎么写
- Python(应用) — Tesseract图片文字识别(一)
- treetable怎么带参数_jQuery.treetable使用及异步加载
- 关闭445端口的方法
- word文档通配符换行_Word指定位置批量插入表格,别人花一天搞不出来,我只用了10秒...
- java熟人_英语中对各种不同程度关系的朋友是怎么表示的(就像汉语里有泛泛之交、熟人、朋友、死党之类的)?...
- 把自己曾经写的一个客户间聊天的程序与大家分享(2)
- tabindex的微妙使用