1:多态(掌握)

(1)多态概念:一种事物的多种形态

(2)体现:父类的引用指向其子类的实例对象;接口的引用指向其实现类的实例对象

(3)特点:

成员方法:编译看左边,运行看右边

   运行:子类重写的方法运行

  编译:父类的引用类型必须有该方法

成员变量:编译看左边,运行看左边

  运行:访问的为父类的属性

   编译:父类的引用类型必须有该属性

  总结:只有在方法调用的时候,才会判断子类是否重写,重写调用子类方法。其他情况均看父类类型

  记忆方法:方法运行看右边,其他看左边

例子:

/*
多态:
一种事物的多种形态
前提:
具有继承关系
特点:
方法:编译看左边,运行看右边
运行:子类重写的方法运行
编译:父类的引用类型必须有该方法
变量:编译看左边,运行看左边
运行:访问的为父类的属性
编译:父类的引用类型必须有该属性
只有在方法调用的时候,才会判断子类是否重写,重写调用子类方法。其他情况均看父类类型
一句话总结:方法运行看右边,其他看左边
*/
class Demo5
{
public static void main(String[] args)
{
Animal animal = new Animal(); //动物是一种动物
Animal animal2 = new Cat(); //猫是一种动物,多态:猫的实例对象,父类动物的引用 //Cat cat2 = new Animal(); //动物是猫,不可以
Cat cat = new Cat(); //猫是猫 Animal a = new Cat();
//成员方法:
a.eat(); //喵吃了
System.out.println(a.name); //巴马
System.out.println(a.age); //
}
} class Animal
{
String name = "巴马";
int age = 80;
public void eat(){
System.out.println("吃了");
}
} class Cat extends Animal
{
String name = "加菲";
int age = 40;
public void eat(){
System.out.println("喵吃了");
}
}

多太内存图:

(4)前提:

   A:有继承或者实现关系。

   B:有方法重写。  (重要)

/**
* 多态的前提条件之一:必须要有方法的覆盖(即重写)
*/
public class Test {
public static void main(String[] args) {
Animal animal = new Dog();
animal.eat();
// animal.sleep(); //报错,找不到符号,接口中没有sleep()抽象方法
}
} //接口
interface Animal {
public abstract void eat();
} class Dog implements Animal {
//继承的方法的重写
public void eat() {
System.out.println("狗吃");
}
//自己的方法
public void sleep() {
System.out.println("夹着尾巴睡");
}
}

   C:有父类引用指向子类对象, 或者接口的应用指向实现类的对象

(3)好处和弊端:

   A:好处

  扩展性和维护性(是由继承和实现保证)。

/*
有两个类猪,狗继承动物,均有吃的动作。
创建多个猪与狗,调用他们吃的功能。
再来一个猫,创建多个猫的对象,调用猫的吃的功能
*/
class Demo8_4
{
public static void main(String[] args)
{ Pig pig = new Pig();
Pig pig2 = new Pig();
Pig pig3 = new Pig(); Dog dog = new Dog();
Dog dog2 = new Dog();
Dog dog3 = new Dog();
/*
Animal pig = new Pig();
Animal pig2 = new Pig();
Animal pig3 = new Pig(); Animal dog = new Dog();
Animal dog2 = new Dog();
Animal dog3 = new Dog();
*/
//不需要调用不同的方法,只需要调用同一个animalEat的方法即可
/*
MyAnimalTool.pigEat(pig);
MyAnimalTool.pigEat(pig2);
MyAnimalTool.pigEat(pig3); MyAnimalTool.dogEat(dog);
MyAnimalTool.dogEat(dog2);
MyAnimalTool.dogEat(dog3);
*/ MyAnimalTool.animalEat(pig);
MyAnimalTool.animalEat(pig2);
MyAnimalTool.animalEat(pig3);
MyAnimalTool.animalEat(dog);
MyAnimalTool.animalEat(dog2);
MyAnimalTool.animalEat(dog3); Cat cat = new Cat();
Cat cat2 = new Cat();
Cat cat3 = new Cat();
/*
Animal cat = new Cat();
Animal cat2 = new Cat();
Animal cat3 = new Cat();
*/
/*
MyAnimalTool.catEat(cat);
MyAnimalTool.catEat(cat2);
MyAnimalTool.catEat(cat3);
*/
MyAnimalTool.animalEat(cat);
MyAnimalTool.animalEat(cat2);
MyAnimalTool.animalEat(cat3);
}
/*
public static void pigEat(Pig p) {
p.eat();
} public static void dogEat(Dog d) {
d.eat();
} public static void catEat(Cat c) {
c.eat();
}
*/
}
//定义动物类作为父类
class Animal
{
public void eat(){
System.out.println("吃");
}
}
//定义猪与狗作为子类
class Pig extends Animal
{
public void eat(){
System.out.println("拱着吃");
}
} class Dog extends Animal
{
public void eat(){
System.out.println("摇着尾巴吃");
}
} class MyAnimalTool
{
//多个动物均是Animal的子类,所以只需要定义一个方法接受Animal类型即可。从而加入新的动物时,该类代码不需要改动!
/*
public static void pigEat(Pig p) {
p.eat();
} public static void dogEat(Dog d) {
d.eat();
} public static void catEat(Cat c) {
c.eat();
}
*/ public static void animalEat(Animal a) {
a.eat();
}
}
//添加猫类
class Cat extends Animal
{
public void eat(){
System.out.println("舔着吃");
}
}

   B:弊端

    不能使用子类的特有功能。

/**
* 多态的前提条件之一:必须要有方法的覆盖(即重写)
*/
public class Test {
public static void main(String[] args) {
Animal animal = new Dog();
animal.eat();
// animal.sleep(); //报错,找不到符号,接口中没有sleep()抽象方法
}
} //接口
interface Animal {
public abstract void eat();
} class Dog implements Animal {
//继承的方法的重写
public void eat() {
System.out.println("狗吃");
}
//自己的方法
public void sleep() {
System.out.println("夹着尾巴睡");
}
}

(4)向上转型和向下转型

   A:向上转型

   把子类对象赋值给父类或者接口引用 ,例子:

/*
向上转型:
引用变量为父类时,子类实例对象可以自动提升为父类类型。即引用为父类型,可以赋值子类实例对象。
*/
class Demo6
{
public static void main(String[] args)
{
Animal a = new Cat(); //多态本身的赋值就是向上转型。
Cat c = new Cat(); //method(c);
//method(new Animal()); 不可以
//method(a); 不可以 method2(a);
method2(c); //向上转型 Cat c2 = method3();
Animal a2 = method3(); //向上转型 //Cat c3 = method4();
Animal a3 = method4();
} public static void method(Cat c) {
System.out.println(c);
} public static void method2(Animal animal) {
System.out.println(animal);
} public static Cat method3(){
//return new Animal();
return new Cat();
} public static Animal method4(){
//return new Animal();
return new Cat(); //向上转型
}
}
class Animal
{
String name = "巴马";
int age = 80; public void eat(){
System.out.println("吃了");
} } class Cat extends Animal
{
String name = "加菲";
int age = 40; public void eat(){
System.out.println("喵吃了");
} }

   B:向下转型

     把父类或者父接口引用强制转换为子类,例子:

/*
向下转型:
将父类强转成子类,前期父类引用指向的对象为子类对象,即必须是多态的引用。
*/
class Demo7
{
public static void main(String[] args)
{
Animal a = new Cat();
Animal a2 = new Animal(); Cat c = (Cat)a;
//Cat c2 = (Cat)a2; 不可以
}
} class Animal
{
String name = "巴马";
int age = 80; public void eat(){
System.out.println("吃了");
} } class Cat extends Animal
{
String name = "加菲";
int age = 40; public void eat(){
System.out.println("喵吃了");
} }

(5)多态中的使用成员特点

   A:成员变量

     编译运行都看左边

    B:成员方法

    编译看左边,运行看右边。

   总结: 全部看父类类型,只是在调用该方法时,检查子类是否重写,如果重写,调用之类方法,如果没有重写,调用父类的方法。

(6)多态的体现形式

   A:具体类多态(几乎不用)

    B:抽象类多态

  C:接口多态

2:抽象类(掌握)

  (1)多个具体的事物具备相同的方法声明,而方法体不同,我们就只抽取方法声明,然后定义到一个类中。

      而一个没有方法体的方法是一个抽象方法,一个类中有抽象方法,该类必须定义为抽象类。

   (2)抽象类的特点:

     A:抽象类或者抽象方法用abstract修饰。

    B:抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。

    C:抽象类不能被实例化。

    D:子类继承抽象类,要么是抽象类,要么重写所有父类抽象方法。

例子:

/*
抽象类:包含抽象方法的类
*/
class Demo9
{
public static void main(String[] args)
{
//Animal a = new Animal();
Animal a2 = new Pig();
System.out.println("Hello World!");
}
}
//定义动物类作为抽象父类
abstract class Animal
{
public abstract void eat();
public abstract void sleep();
//public void sleep(){
// System.out.println();
//}
}
//定义猪与狗作为子类
class Pig extends Animal
{
public void eat(){
System.out.println("拱着吃");
} public void sleep(){
System.out.println("躺着睡");
}
}
/*
abstract class Dog extends Animal
{
public void eat(){
System.out.println("摇着尾巴吃");
}
}
*/
class Dog extends Animal
{
public void eat(){
System.out.println("摇着尾巴吃");
}
public void sleep(){
System.out.println("压着尾巴睡");
}
}

(3)抽象类的几个小问题

   A:不能被实例化,要构造方法干啥?

    给抽象类的成员变量赋值

    B:一个类中没有抽象方法,居然定义抽象类,有什么意义?

   强制不让该类创建对象

    C:abstract抽象关键字不能和哪些关键字共存

     a:private  抽象类的方法需要被覆盖,如果private修饰的话,子类无法访问

    b:final   抽象类需要继承,final修饰的无法继承

    c:static   抽象类抽象方法无方法体,调用无意义

(4)抽象类的成员:

    A:成员变量 有变量,也有常量

   B:构造方法 有构造方法,用于子类访问父类数据的初始化

   C:成员方法 有抽象方法,也有非抽象的方法

(5)抽象类的案例

A:老师案例

例子:

/*
老师示例
具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。
*/
class Test
{
public static void main(String[] args)
{
BaseTeacher bt = new BaseTeacher("刘正风",28);
bt.setName("曲阳");
bt.teach();
System.out.println(bt.getName());
bt.teach(); WorkTeacher wt = new WorkTeacher("唐嫣",28);
wt.teach(); Teacher t = new BaseTeacher("刘正风",28);
t.setName("曲阳");
t.teach();
System.out.println(t.getName()); Teacher t2 = new WorkTeacher("唐嫣",28);
t2.teach();
}
}
//设计抽象概念老师类
abstract class Teacher
{
private String name;
private int age; public Teacher(){}
public Teacher(String name,int age){
this.name = name;
this.age = age;
} public abstract void teach(); public void setName(String name) {
this.name = name;
} public String getName() {
return name;
} public void setAge(int age) {
this.age = age;
} public int getAge() {
return age;
}
} //定义基础班老师
class BaseTeacher extends Teacher
{
public BaseTeacher(){}
public BaseTeacher(String name,int age){
super(name,age);
} public void teach() {
System.out.println("讲JavaSE");
}
} //定义就业班老师
class WorkTeacher extends Teacher
{
public WorkTeacher(){}
public WorkTeacher(String name,int age){
super(name,age);
} public void teach() {
System.out.println("讲JavaEE/Android");
}
}

3:接口(掌握)

(1)当一个抽象类中的方法都是抽象的时候,java就提供了一种更抽象的表达方式,叫接口。(接口里面的方法都是抽象的)

   a.定义接口:interface XX {}

   b.使用接口:class YY implements XX{}

例子:

/*
比抽象类更为抽象的表现形式
格式:
定义接口:interface XX {}
使用接口:class YY implements XX{} */
class Demo11
{
public static void main(String[] args)
{
//Cat cat = new Cat();
Cat cat2 = new Student();
Cat cat3 = new Person();
System.out.println("Hello World!");
}
} interface Cat
{
public abstract void climb();
} interface Dog
{
public abstract void guanxianshi();
} class Animal
{
} class Person extends Animal implements Cat,Dog
{
public void climb(){
System.out.println("我爬了");
} public void guanxianshi(){
System.out.println("我就管了");
}
} class Student extends Animal implements Cat
{
public void climb(){
System.out.println("我爬了");
} public void guanxianshi(){
System.out.println("我就管了");
}
}

(2)接口的成员特点:

   A:成员变量 是常量 默认修饰符 public static final

   B:成员方法 抽象方法 默认修饰符 public abstract

   c: 没有构造方法 (接口不能创建对象)

例子:

/*
接口的成员有固定修饰符:
变量:public static final 将变量变为常量,所以必须显示初始化
方法:public abstract 一定为公共的抽象方法
*/
class Demo12
{
public static void main(String[] args)
{
Computer c = new Person();
c.play(); System.out.println(Computer.NO1);
}
} interface Computer
{
//public static final String NO1 = "艾尼阿克";
String NO1 = "艾尼阿克";
//public abstract void play();
//public void play();
void play();
//private void play(); 不能使用其他访问权限修饰符 } class Person implements Computer
{ public void play(){
System.out.println("敲个猜数字");
}
/* 不能使用默认的访问权限覆盖公共的访问权限
void play(){
System.out.println("敲个猜数字");
}
*/
}

(3)接口的特点:

    A:接口用interface定义

   B:实现类实现接口用implements标识

    C:接口不能被实例化

      D:子类实现接口的时候,要么是抽象类,要么全部实现接口方法

(4)接口和类的关系

   A:类与类的关系

     继承关系,只能单继承,可以多层继承。

   B:类与接口的关系

      实现关系,可以单实现,也可以多实现。

    还可以在继承一个类的同时,实现多个接口。 class A extends B implements C,D

   C:接口与接口的关系

     继承关系,可以单继承,也可以多继承。

(5)接口的思想特点(理解)

    A:对外暴露的规则(USB接口)

    B:程序的扩展功能(多态)

    C:降低程序的耦合性(多态)

   D:让类可以多实现

(6)接口和抽象类的区别

   共性:都是不断抽取出来的抽象的内容。都不能创建实例对象。

  不同:

    A:成员特点

  抽象类:

     成员变量 可以变量,也可以常量

    成员方法 可以抽象,也可以非抽象

     构造方法 有

   接口:

     成员变量 只能是常量, 固定修饰符public static final

    成员方法 只能是抽象,固定修饰符public abstract

    构造方法 无

  B:继承或者实现关系特点

    a:类与类的关系(继承 extends)

     继承关系,只能单继承,可以多层继承。

     b:类与接口的关系(实现 implements)

     实现关系,可以单实现,也可以多实现。

     还可以在继承一个类的同时,实现多个接口。

      c:接口与接口的关系(继承 extends)

    继承关系,可以单继承,也可以多继承。

C:设计区别

   抽象类中定义的是体系的共性内容。表达的是:is a的关系。

   接口中定义的是体系的扩展功能。表达的是:like a的关系。

简单总结:

   均为抽取出的相同概念的抽象。都不能创建实例对象。

    类为单继承,接口为多实现。

   继承为”is a”的关系,接口为“like a”的关系。

     抽象类中可以定义非抽象方法,共子类直接使用。接口均为抽象方法,因为固定修饰符。

(7)如何实现一个继承体系

分析:由具体到抽象

实现:由抽象到具体

多态、抽象类、接口_DAY09的更多相关文章

  1. 【Java基础】【09面向对象_多态&抽象类&接口】

    09.01_面向对象(多态的概述及其代码体现) A:多态(polymorphic)概述 事物存在的多种形态 B:多态前提 a:要有继承关系. b:要有方法重写. c:要有父类引用指向子类对象. C:案 ...

  2. 06 面向对象:多态&抽象类&接口&权限修饰符&内部类

    多态: /* 多态(polymorphic)概述 * 事物存在的多种形态 多态前提 * a:要有继承关系. * b:要有方法重写. * c:要有父类引用指向子类对象. * 成员变量 * 编译看左边(父 ...

  3. PHP中多态,抽象类,接口,

    小例子: 需求:公司定义一个接口让我们开发功能 usb.interface.php: <?php interface USB{ public function run(); } store.cl ...

  4. -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal

    java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型  也就是 ...

  5. python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)

    一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...

  6. python面向对象 : 抽象类(接口类),多态,封装(私有制封装)

    一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...

  7. 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装

    抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...

  8. python day - 19 抽象类 接口类 多态 封装

    一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...

  9. java 面向对象面试题,问答题,构造方法,抽象类,继承,多态,接口,异常总结;

    一,构造方法的特点 面向对象的思想是如何在java展现的呢? 就是通过类和对象 类是一组相关的属性和行为的集合.是一个抽象的概念. 对象是该类事物的具体表现形式.具体存在的个体. 一.抽象类的抽象方法 ...

  10. Java开发知识之Java的继承多态跟接口*

    Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...

随机推荐

  1. VMware14 安装CentOS7及其配置;CentOS7配置网桥,做远程连接;

    1.VMware14安装        进入百度链接,按照图形安装就好了.https://jingyan.baidu.com/article/9f7e7ec09da5906f281554d6.html ...

  2. IntelliJ IDEA 2017版 使用笔记(十一) Debug操作:IDEA 快捷键

    调试功能;            缩短项目时间,调高阅读源码的能力.   一.添加断点,选中一行代码,双击即可生成断点(快捷键:ctrl+F8)                二.单步运行,快捷键:s ...

  3. new命令简化的内部流程

    构造函数返回对象的一些问题: function fn(name,age){ this.name = name; this.age = age; //return 23; 忽略数字,直接返回原有对象 / ...

  4. php 制作二维码 phpqrcode.php

    phpqrcode.php 下载地址:https://sourceforge.net/projects/phpqrcode/ //测试可行 utf-8格式 <?php header(" ...

  5. ==和equals的比较

    一 : == 的特点: a == b ; 1.如果A和B是基本数据类型    ==   比较的是两个变量的值 2.如果A和B是引用数据类型    == 比较的是两个变量的内存地址 二:重写的equal ...

  6. std::string的find问题研究

    https://files-cdn.cnblogs.com/files/aquester/std之string的find问题研究.pdf 目录 目录 1 1. 前言 1 2. find字符串 1 3. ...

  7. day35(servlet 3.0)

    servlet3.0的问题 Servlet3.0与Servlet2.5提供了三个新特性: * 注解开发   :方便 * 文件上传   :有些API不是特别全. * 异步请求   :多线程的实现 注解开 ...

  8. hdu 5060 五种情况求圆柱体与球体交

    http://acm.hdu.edu.cn/showproblem.php?pid=5060 官方题解http://bestcoder.hdu.edu.cn/给复杂了 实际上用圆柱体与球体体积差的积分 ...

  9. shell 命令 netstat 查看端口占用

    netstat 查看 8888端口的占用情况

  10. adb push 和 adb pull命令

    adb push命令 :从电脑上传送文件到手机: adb pull命令 :从手机传送文件到电脑上             @Cocos 下次需要权限的目录可以执行chmod 777 目录名      ...