目录
1. 多态
多态:指的是同一个对象,在不同时刻表现出来的多种形态
多态的前提和实现
多态中成员的访问特点
多态的好处和弊端
多态中的转型
2. 抽象类
2.1 概述
2.2 抽象类特点:
3 . 接口
3.1概述
3.2 接口特点
3.3 多态的三种形式
3.4 接口的成员特点
3.5 类和接口的关系
3.6 抽象类和接口的区别
作业:盖房子
例如:动物 animal = new 猫();
有继承/实现关系
有方法重写
有父类引用指向子类对象
成员变量:编译看左边,运行也看左边-->等号左边看父类
成员方法:编译看左边(父类),运行看右边(子类)
因为成员方法可以重写,变量不能重写
多态练习
package com.itheima;
//人类
public class Person {
//定义一个变量
public int age = 40;
//定义一个睡觉方法
public void sleep(){
System.out.println("人要睡够八小时");
}
}
//学生类
class Student extends Person{
int age = 20;
String play = "打篮球";
@Override
public void sleep() {
// super.sleep();
System.out.println("学生要学习,一天只睡六小时");
}
}
//测试类
class Demo{
public static void main(String[] args) {
//创建对象
Person person = new Student();
// person.play;编译看左边,走父类中的逻辑父类不存在play变量,故编译报错,
System.out.println(person.age);//变量:编译看左边,运行看左边
//调用方法
person.sleep();//方法:编译看左边,运行看右边
}
}
好处:提高了代码的扩展性(体现在参数和返回值类型)
1.定义方法时,将参数(形参)写成父类型,那么该方法就可以接受该父类型,所有的子类对象(实参)
弊端:不能直接使用子类特有的功能,编译看左边,父类没有的变量或者方法,就不能执行
从下向上转型
父类引用指向子类对象(类似隐式转换)
例如:动物 a = new 猫
从上向下转型
父类引用转为子类对象类似于强制转换()
在java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
package com.itheima03;
//定义一个抽象的动物类
public abstract class Animal {
public abstract void eat();//不能明确具体功能的方法,可以定义为抽象方法
}
//测试类
class Demo{
public static void main(String[] args) {
//Animal a = new Animal() 抽象类不能实例化对象
Animal a = new Cat();//采用多态的形式创建对象
a.eat();
}
}
//猫类
class Cat extends Animal{
@Override
public void eat() {
//super.eat();
System.out.println("猫吃鱼");
}
}
抽象类和抽象方法必须使用abstract 关键字修饰
public abstract class 类名{}
public abstract void eat();//没有方法体的方法
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能实例化,可以参照多态的方式,通过子类对象实例化,称为抽象类多态
抽象类的子类,要么重写抽象类中的所有抽象方法(常用),要么是抽象类(不常用)
2.3 抽象类成员特点
成员变量:可以是变量,也可以是常量
构造方法:有构造方法,但是不能实例化.
主要作用用于子类初始化访问父类数据,因为子类构造第一句默认是super访问父类的空参构造
成员方法:可以有抽象方法:限定子类必须完成某些动作
也可以有非抽象方法,提高代码复用性
package com.itheima03;
//抽象人类
public abstract class Person {
//成员变量,姓名,年龄
private String name;
private int age;
//构造方法,无参带参
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//成员方法:get/set,吃
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 Teacher extends Person {
//构造方法:无参,带参
public Teacher() {
}
public Teacher(String name, int age) {
super(name, age);
}
//成员方法:吃
@Override
public void eat() {
System.out.println("老师吃鼠标,讲课越来越棒");
}
}
//定义学生类,继承人类,重写吃的方法
class Student extends Person {
//构造方法:无参,带参
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
//成员方法:吃
@Override
public void eat() {
System.out.println("学生吃键盘,技术越来越好");
}
}
//定义测试类
class Demo01 {
public static void main(String[] args) {
Person p = new Teacher();
p.setName("刘德华");
p.setAge(28);
System.out.println(p.getName() + ", " + p.getAge());
p.eat();
p = new Teacher("张国荣", 39);
System.out.println(p.getName() + ", " + p.getAge());
p.eat();
p = new Student("张国荣", 39);
System.out.println(p.getName() + ", " + p.getAge());
p.eat();
}
}
接口就是一种公共的规范标准,只要符合规范标准,大家都可以使用
Java中的接口更多体现在对行为的抽象
接口用interface 关键字声明
public interface 接口名{}
类实现接口使用implements关键字完成
public class 类名 implements 接口名{}
接口不能直接实例化(不能创建对象),可以参照多态,通过类对象实例化,称为接口多态
多态的形式:具体类多态,抽象类多态,接口多态
接口的实现类
要么重写接口的所有抽象方法,要么是抽象类
package com.itheima03.Text01;
//1.接口使用interface声明
public interface Inter {
//写一个抽象方法
public abstract void method();
}
package com.itheima03.Text01;
//2.实现接口使用implements关键字完成
//重写接口中的所有抽象方法
public class InterImp implements Inter{
@Override
public void method() {
System.out.println("实现类中method方法重写...");
}
}
//4.接口的实现类要么重写接口中所有的抽象方法(常用),要么将自己定义为抽象类(不常用没意义)
//abstract class InterImpl implements Inter{
package com.itheima03.Text01;
public class Demo {
public static void main(String[] args) {
//3.接口不能直接实例化对象,可以通过多态的形式
InterImp i= new InterImp();
i.method();//实现类中重写的method方法
//接口多态:父类引用指向子类对象
Inter ii = new InterImp();
ii.method();//实现类中重写的method方法
}
}
具体类形态
抽象类对象
接口多态
成员变量:只能是常量.默认修饰符:public static final
没有构造方法,接口主要是扩展功能的,,而没有具体存在
一个类如果没有父类,默认继承Object类
成员方法:只能是抽象方法 (在JDK7之前) 默认修饰符:public abstract
注意事项:接口中的方法都是抽象方法,而且没有构造方法,因为接口主要是扩展功能,没有具体的存在,比抽象类还要抽象的东西,就是接口
1. 类和类
继承关系,只能单继承,不能多继承
2. 类和接口
实现关系,可以单实现,也可以多实现还可以在继承一个类的同时实现多个接口
3. 接口和接口的关系?
继承关系,可以单继承,也可以多继承
成员区别
抽象类:变量,常量;有构造方法,抽象方法
接口:常量,抽象方法
关系区别
类与类:继承关系;单继承
类与接口:实现关系,单实现,多实现
接口与接口:继承关系,单继承,多继承
设计理念的区别
抽象类:对类抽象,包括属性和行为
接口:对行为抽象,主要是行为
需求描述:请使用模板设计模式设计一个建房子的模板类,并提供两个子类使用。程序的运行结果如下所示:
实现提示:
1、模板类中提供一个成员变量让用户设置房子的名称,通过构造方法给成员变量赋值
2、在模板类中提供一个建造房子的非抽象方法定义建造房子的过程
3、在模板类中提供指定的抽象方法用于子类进行实现
造一个盖房子的模板,根据用户的需求,再重写盖房子所需要的材料
public abstract class Home {
//封装一个名字
private String name;
//构造方法:空参,带参
public Home() {
}
public Home(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//
protected abstract void foundation();//地基
protected abstract void wall();//墙
protected abstract void door();//门
protected abstract void window();//窗
//定义一个非抽象方法,建房子的模板
public final void makeHouse(){
foundation();
wall();
door();
window();
}
}
房子1
public class Hom1 extends Home{
@Override
public void setName(String name) {
super.setName(name);
}
@Override
protected void foundation() {
System.out.println(getName()+"的地基要使用钢铁地基");
}
@Override
protected void wall() {
System.out.println(getName()+"的墙要使用大理石建造");
}
@Override
protected void door() {
System.out.println(getName()+"的门要采用防盗门");
}
@Override
protected void window() {
System.out.println(getName()+"的窗要面向北方");
}
}
房子2
public class Home2 extends Home{
@Override
public void setName(String name) {
super.setName(name);
}
@Override
protected void foundation() {
System.out.println(getName()+"的地基要使用huagany");
}
@Override
protected void wall() {
System.out.println(getName()+"的墙要使用玻璃制造");
}
@Override
protected void door() {
System.out.println(getName()+"的门采用门门");
}
@Override
protected void window() {
System.out.println(getName()+"的窗户要朝南");
}
}
测试验房
public class HomeDemo {
//测试类
public static void main(String[] args) {
Home h = new Hom1();
h.setName("房子1");
h.makeHouse();
h = new Home2();
h.setName("房子2");
h.makeHouse();
}
}