在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
抽象类特点a.抽象类和抽象方法必须用abstract关键字修饰
格式:
abstract class 类名 {}
public abstract void eat(); (抽象方法)
b.抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
c.抽象类不能实例化
那么,抽象类如何实例化呢? 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
d.抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法
例:
abstract class Animals2{ //定义一个抽象的动物类 public abstract void eat(); //定义一个抽象的方法 public abstract void character(); //定义父类的第二个抽象方法 } class Sheep2 extends Animals2{ @Override public void eat(){ System.out.println("羊吃草"); //重写父类中的抽象方法 } @Override public void character() { System.out.println("羊很温顺"); } } class Wolf2 extends Animals2{ @Override public void eat(){ System.out.println("狼吃肉"); //重写父类中的抽象方法 } @Override public void character() { System.out.println("狼很残暴"); } } public class Test4 { public static void main(String[] args) { //多态创建对象 Animals2 s=new Sheep2(); s.eat(); s.character(); Animals2 w =new Wolf2(); w.eat(); w.character(); } }抽象类的成员特点
a.成员变量
可以是变量
也可以是常量
b.构造方法
有构造方法,但是不能实例化
那么,构造方法的作用是什么呢? 用于子类访问父类数据的初始化
c.成员方法
可以有抽象方法 限定子类必须完成某些动作
也可以有非抽象方法 提高代码服用性
案例:假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。 经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。 请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
abstract class Staff{ //定义员工的成员变量 private String name; private String number; private int wage; public Staff() { } //无参构造方法 public Staff(String name, String number, int wage) { //有参构造方法 this.name = name; this.number = number; this.wage = wage; } //get方法 public String getName() { return name; } public String getNumber() { return number; } public int getWage() { return wage; } public abstract void work(); //定义父类抽象方法 public void show(){ System.out.println("姓名:"+name); System.out.println("工号:"+number); System.out.println("工资:"+wage); } } class Manager extends Staff{ //经理类 private int bonus; //经理特有的奖金属性 public Manager(String name, String number, int wage, int bonus) { //子类有参构造方法 super(name, number, wage); this.bonus = bonus; } @Override public void work() { System.out.println("工作:管理员工"); //重写抽象类方法 } public void show2(){ System.out.println("奖金:"+bonus); } } class GeneralStaff extends Staff{ //普通员工类 public GeneralStaff(String name, String number, int wage) { super(name, number, wage); } @Override public void work() { System.out.println("工作:写程序"); } } public class Test5 { public static void main(String[] args) { //多态创建经理对象 Staff s1 =new Manager("经理","00001",100000,20000); s1.show(); s1.work(); //向下转型,访问子类特有方法 Manager manager= (Manager) s1; manager.show2(); System.out.println("================================"); //多态创建普通员工对象 Staff s2 =new GeneralStaff("普通员工","00002",20000); s2.show(); s2.work(); } }抽象类中的问题
a.一个类没有抽象方法能不能定义为抽象类?如果有,有何意义?
可以,例如水和饮料都有共同的特点,我们把这些相同的概念归结成一个类,都是液体。至于后面有没有抽象方法,取决于他们有没有共同的功能,如果只是有相同的本质,没有实际相同的行为,我们只定义抽象类不写抽象方法是可以的。
b.abstract不能和哪些关键字共存
private 冲突
final 冲突
static 无意义
接口 接口特点a.接口用关键字interface表示
格式:interface 接口名 {}
b.类实现接口用implements表示
格式:class 类名 implements 接口名 {}
c.接口不能实例化
那么,接口如何实例化呢? 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
d.接口的子类
要么是抽象类
要么重写接口中的所有抽象方法
例:
abstract class OldPhone{ //定义一个抽象的父类 public abstract void call(); } interface Phone{ //定义一个接口Phone public void play(); } class NewPhone extends OldPhone implements Phone{ //定义一个OldPhone类继承NewPhone类并实现接口 @Override public void call() { System.out.println("打电话"); //重写父类中的抽象方法 } @Override public void play() { System.out.println("玩游戏"); //重写接口里面的方法 } public void watch(){ System.out.println("看视频"); //子类特有方法 } } public class interfaceTest1 { public static void main(String[] args) { //多态创建NewPhone的对象 OldPhone a= new NewPhone(); a.call(); //OldPhone里没有play和watch的方法。向下转型 NewPhone b =(NewPhone) a; b.play(); b.watch(); } }接口成员特点
a.成员变量
只能是常量 默认修饰符 public static final
例:
interface A{ int s= 100; } class B implements A{ } public class interfaceTest2 { public static void main(String[] args) { A a= new B(); a.s=1000; } }
我们通过Java反编译工具可以看到这里隐藏的修饰
b.构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
(虽然接口中没有构造方法,但多态初始化的时候会先初始化父类在初始化子类,java中所有的类都有一个父类叫Object,每个class都有Object作为父类)
c.成员方法
只能是抽象方法 默认修饰符 public abstract
例:同样 我们可以在接口例添加一个方法,通过反编译工具看到隐藏的修饰
类与类,类与接口以及接口与接口的关系
a.类与类
继承关系,只能单继承,但是可以多层继承
class A1{} class B1 extends A1{} class C1 extends B1{}
b.类与接口
实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口
interface Inter1{} interface Inter2{} class C extends Object implements Inter1,Inter2{}
c.接口与接口
继承关系,可以单继承,也可以多继承
interface Inter1{} interface Inter2{} interface Inter3 extends Inter1,Inter2{}抽象类和接口的区别
1. 成员区别
a.抽象类 : 变量,常量;有抽象方法;抽象方法,非抽象方法
b.接口: 常量;抽象方法
2.关系区别
a.类与类 :继承,单继承
b.类与接口: 实现,单实现,多实现
c.接口与接口 :继承,单继承,多继承
3.设计理念区别
a.抽象类 被继承体现的是:”is a”的关系。共性功能
b.接口 被实现体现的是:”like a”的关系。扩展功能
教练和运动员案例:
a.乒乓球运动员和篮球运动员;乒乓球教练和篮球教练。
b.为了出国交流,跟乒乓球相关的人员都需要学习英语。
c.请用所学知识: 分析,这个案例中有哪些抽象类,哪些接口,哪些具体类。
abstract class Person{ //定义一个抽象的人类 private String name; private int age; //定义成员变量 public Person() {} //无参构造方法 public Person(String name, int age) { //有参构造方法 (快捷键alt+insert) this.name = name; this.age = age; } //set和get方法 public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void show(){ //定义一个展示的方法 System.out.println("姓名:"+name+",年龄:"+age); } } class SportsMan extends Person{ //创建运动员类继承人类 //无参,有参构造方法 public SportsMan() {} public SportsMan(String name, int age) { super(name, age); } } class Coach extends Person{ //创建教练类继承人类 //有参,无参构造方法 public Coach() {} public Coach(String name, int age) { super(name, age); } } interface English{ //创建一个English接口 public abstract void study(); //这里即使写不写abstract都一样,默认abstract修饰,初学者可以写一下。 } class PingPongSports extends SportsMan implements English{ //创建乒乓球运动员类继承SportsMan类并实现English接口 public PingPongSports(String name, int age) { super(name, age); } @Override //重写接口中的抽象方法(快捷键 alt+Enter) public void study() { System.out.println("乒乓球运动员学习英语"); } } class BasketballSports extends SportsMan{ //创建篮球运动员继承SportsMan类 public BasketballSports(String name, int age) { super(name, age); } } class PingPongCoach extends Coach implements English{ //创建乒乓球教练类继承SportsMan类并实现English接口 public PingPongCoach(String name, int age) { super(name, age); } @Override //重写接口中的抽象方法 public void study() { System.out.println("乒乓球教练学习英语"); } } class BasketballCoach extends Coach{ //创建篮球教练继承教练类 public BasketballCoach(String name, int age) { super(name, age); } } public class interfaceTest3 { public static void main(String[] args) { //创建一个乒乓球运动员对象 SportsMan s1 = new PingPongSports("乒乓球运动员",18); s1.show(); //向下转型,访问子类特有方法 PingPongSports p =(PingPongSports) s1; p.study(); // ((PingPongSports) s1).study() ,把这两个合成一个都行 System.out.println("================="); //创建一个篮球教练的对象 Coach s2 =new BasketballCoach("篮球教练",40); s2.show(); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)