您的位置:首页 > 职场人生

黑马程序员_Java语言_面向对象_多态

2015-05-03 14:08 281 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

09.01_面向对象(多态的概述及其代码体现)

A:多态概述

事物存在的多种形态

B:多态前提

a:要有继承关系。

b:要有方法重写。

c:要有父类引用指向子类对象。

C:案例演示

代码体现多态

/*
程序中的多态
父类的引用 = 自己的子类的对象
*/
class Fu
{
public void show(){
System.out.println("父类的show");
}
}
class Zi extends Fu
{
public void show(){
System.out.println("子类重写show");
}
}
class Zi1 extends Fu
{
public void show(){
System.out.println("子类重写show1111");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
Fu f = new Zi();
f.show();
//. System.out.println("Hello World!");
}
}


09.02_面向对象(多态中的成员访问特点)

A:多态中的成员访问特点

a:成员变量

编译看左边,运行看左边

b:成员方法

编译看左边,运行看右边

c:静态方法

编译看左边,运行看左边

(静态和类相关,算不上重写,所以,访问还是左边的)

B:案例演示

多态中的成员访问特点

/*
多态中,子类父类中成员访问的特点
*/
class Fu
{
int i = 3;
public static void show(){
System.out.println("父类..show");
}
}
class Zi extends Fu
{
int i = 4;
public static void show(){
System.out.println("子类..show");
}
}
class DuoTaiDemo1
{
public static void main(String[] args)
{
//多态形式进行调用
Fu f = new Zi();
f.show();
//System.out.println(f.i);
}
}


09.03_面向对象(故事)

人: 军人,老百姓,老板

09.04_面向对象(多态中向上转型和向下转型)

A:案例演示

详细讲解多态中向上转型和向下转型

父类是Animal,子类是Cat

Animal a = new Cat();向上转型

Cat c = new Animal();错误的

Cat c = (Cat)a;向下转型

Cat c = new Cat();

Animal a = (Animal)c; //其实加不加Animal都是一样的,都是向上转型

//c其实就是猫

B: 多态转型中的类型判断 instanceof运算符

java.lang.ClassCastException 类型转换异常

案例:将Dog对象,强制转成了Cat

关键字,也是运算符 instanceof 运算结果是布尔类型

检查 引用变量是不是这个类创建的

Animal a = new Dog();

Cat c = (Cat)a;

instanceof 判断出变量a 是不狗类创建的对象

固定格式:

引用变量 instanceof 类

a instanceof Dog 判断a 是不是狗类对象,如果是运算符返回true

写在if语句中

使用子类特有功能,需要强制转换,保证安全,使用instanceof判断

C: 多态的设计原理

为什么多态中,有的走父类,有的走子类

编译为什么看左边 Fu f = new Zi();

编译期间特点,检查语法问题,变量没有值,对象也是不存在

编译的时候,看见左边的类类型变量,看不到对象具体是谁

除了非静态的成员方法以外,运行时期,JVM静态的绑定在父类的引用中

但是如果运行的是非静态成员方法,运行时期,JVM动态绑定在子类的对象中,会调用子类的重写方法

为什么,必须运行子类重写方法,设计的原因,扩展父类

子类重写父类方法,目的就为了沿袭父类功能,扩展自己的功能

后面知识点 抽象类,接口,方法是没有主体

public abstract void aa(); 这样的方法根本不能运行

抽象的方法,没有主体的,没有大括号的方法,只能依赖子类重写

09.05_面向对象(多态的好处和弊端)

A:多态的好处

a:提高了代码的维护性(继承保证)

b:提高了代码的扩展性(由多态保证)

B:案例演示

多态的好处

C:多态的弊端

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

D:案例演示

多态的弊端

/*
孔O装爹案例
有2个事物,一个是孔O,他爹
他爹:
年龄:70
讲学功能:经商

孔O:
年龄:40
讲学功能:论语
玩游戏:  和徒弟一起丢手绢

有人找孔O爹,讲学,但是没找到,孔O在家,
化妆成他爹,去讲学。
你的年龄:70

回家,徒弟找他玩游戏,
卸妆变回他自己,打游戏
*/
class KongZiDie
{
int age = 70;
public void teacher(){
System.out.println("经商");
}
}
class KongZi extends KongZiDie
{
int age = 40;
public void teacher(){
System.out.println("论语");
}
public void playGame(){
System.out.println("打游戏");
}
}
class DuoTaiDemo2
{
public static void main(String[] args)
{
//有人找孔O爹,讲学,但是没找到,孔O在家,
//化妆成他爹,去讲学。
KongZiDie k = new KongZi();//孔O提升为了父类类型
k.teacher();
System.out.println(k.age);

//使用打游戏功能,不可以,是子类特有功能,多态弊端
//k.playGame();
//孔O卸妆,由孔O爹变成孔O,大转向为小的,强制转换
//目标类型 变量 = (目标类型)被转数据
KongZi z = (KongZi)k;
z.playGame();
}
}


09.06_面向对象(多态中的题目分析题)

A:看下面程序是否有问题,如果没有,说出结果

class Fu {
public void show() {
System.out.println("fu show");
}
}

class Zi extends Fu {
public void show() {
System.out.println("zi show");
}

public void method() {
System.out.println("zi method");
}
}

class Test1Demo {
public static void main(String[] args) {
Fu f = new Zi();
f.method();//错误,父类未定义method()方法//The method method() is undefined for the type Fu
f.show();
}
}


B:看下面程序是否有问题,如果没有,说出结果

class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
public void show2() {
System.out.println("爱");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class Test2DuoTai {
public static void main(String[] args) {
A a = new B();
a.show();

B b = new C();
b.show();
}
}//爱
你


09.07_面向对象(抽象类的概述及其特点)

A:抽象类概述

B:抽象类特点

a:抽象类和抽象方法必须用abstract关键字修饰

abstract class 类名 {}

public abstract void eat();

b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类

c:抽象类不能实例化那么,抽象类如何实例化呢?

按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。

d:抽象类的子类

要么是抽象类

要么重写抽象类中的所有抽象方法

C:案例演示

抽象类特点

/*
定义抽象类
定义抽象方法
*/
abstract class Abstract
{
public abstract void show();
}
//定义子类继承抽象类,重写抽象方法,建立子类的对象
class SubAbstract extends Abstract
{
//重写抽象方法,去掉修饰符abstract,加上方法体
public void show(){
System.out.println("重写抽象方法");
}
}
class AbstractClassDemo
{
public static void main(String[] args)
{
//创建抽象类的子类对象
SubAbstract sub = new SubAbstract();
sub.show();
//写成多态调用
Abstract a = new SubAbstract();
a.show();
//System.out.println("Hello World!");
}
}


09.08_面向对象(抽象类的成员特点)

A:抽象类的成员特点

a:成员变量:既可以是变量,也可以是常量。

b:构造方法:有。

用于子类访问父类数据的初始化。

c:成员方法:既可以是抽象的,也可以是非抽象的。

B:案例演示

抽象类的成员特点

abstract class Abstract
{
Abstract(){
super();
}
public static int i = 1;
public void show(){}

public abstract void function();

public static void haha(){
System.out.println("hahahah");
}
}

class AbstractClassDemo1
{
public static void main(String[] args)
{
Abstract.haha();
System.out.println(Abstract.i);
}
}


C:抽象类的成员方法特性:

a:抽象方法 强制要求子类做的事情。

b:非抽象方法 子类继承的事情,提高代码复用性。

09.09_面向对象(作用)

案例演示

抽象类的作用

整个继承体系最顶层类,所有子类…都具备,强制子类重写抽象方法,保证继承体系完整.

abstract class Abstract
{
public final void show(){System.out.println("Hello World!");}
public  void haha(){}
}
class SubAbstract extends Abstract
{

}

class AbstractClassDemo2
{
public static void main(String[] args)
{
new SubAbstract().show();
//  System.out.println("Hello World!");
}
}


09.10_面向对象(抽象类练习猫狗案例)

A:案例演示

具体事物:猫,狗

共性:姓名,年龄,吃饭

猫的特性:抓老鼠

狗的特性:看家

/*
具体事物:猫,狗
共性:姓名,年龄,吃饭

抽象类存在意义:强制子类重写抽象方法
抽象类,是整个继承体系的最顶层类,里面功能所有小弟都具备的
抽象类保证继承体系的完整性
猫:存在的时候,应该具有姓名和年龄
创建对象的时候,猫必须具有姓名和年龄,创建对象赋值成员变量,使用构造器
*/
abstract class Animal
{
private String name;
private int age;
Animal(String name,int age){
this.name = name;
this.age = age;
}
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;
}
public abstract void eat();
}
class Cat extends Animal
{
Cat(String name,int age){
//super调用父类构造器,完成成员变量赋值
super(name,age);
}
public void eat(){
System.out.println("猫吃猫粮"+getName()+"..."+getAge());
}
}
class Dog extends Animal
{
Dog(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("狗啃骨头"+getName()+"..."+getAge());
}
}
class AbstractTest
{
public static void main(String[] args)
{
Animal c = new Cat("小白",1);
c.eat();

//修改猫名字和年龄 set
c.setName("机器猫");
c.setAge(2);

c.eat();
System.out.println(c.getName()+"..."+c.getAge());
}
}


09.11_面向对象(抽象类练习老师案例)

A:案例演示

具体事物:基础班老师,就业班老师

共性:姓名,年龄,讲课。

/*
具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。
*/
//将老师共性内容抽取,一个父类
abstract class Teacher
{
private String name;
private int age;
Teacher(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){this.name=name;}
public void setAge(int age){this.age=age;}
public String getName(){return name;}
public int getAge(){return age;}
public abstract void teacher();
}
//定义基础老师,姓名年龄,讲课功能
class BaseTeacher extends Teacher
{
BaseTeacher(String name,int age){super(name,age);}
public void teacher(){
System.out.println("JAVA基础SE");
}
}
//定义就业班老师,姓名年龄,讲课功能
class AdvancedTeacher extends Teacher
{
AdvancedTeacher(String name,int age){super(name,age);}
public void teacher(){
System.out.println("JAVA企业班EE");
}
}
//定义就业辅导老师,姓名年龄,讲课功能
class JobTeacher extends Teacher
{
JobTeacher(String name,int age){super(name,age);}
public void teacher(){
System.out.println("面试技巧");
}
}
class AbstractTest1
{
public static void main(String[] args)
{
//多态形式调用老师的功能
/*Teacher t = new BaseTeacher("张三",101);
t.teacher();
System.out.println(t.getName()+"..."+t.getAge());

t = new AdvancedTeacher("李四",29);
t.teacher();
System.out.println(t.getName()+"..."+t.getAge());

t = new JobTeacher("王五",44);
t.teacher();
System.out.println(t.getName()+"..."+t.getAge());*/

//调用teacher传递Teacher的子类对象
teacher(new BaseTeacher("张三",100));
teacher(new BaseTeacher("张三丰",30));
}
//定义方法,将main重复代码抽取方法
public static void teacher(Teacher t){
t.teacher();
System.out.println(t.getName()+"..."+t.getAge());
}
}


09.12_面向对象(抽象类练习员工案例)

A:案例演示

假如我们在开发一个系统时需要对程序员类进行设计,程序员包含3个属性:姓名、工号以及工资。

经理,除了含有程序员的属性外,另为还有一个奖金属性。

请使用继承的思想设计出程序员类和经理类。要求类中提供必要的方法进行属性访问。

/*
员工与经理
继承思想,共性抽取
采用两种方法创建子类对象
先创建子类对象,调用set方法赋值
再来一种,创建子类对象同时赋值变量
*/
//共性抽取,奖金不能动
abstract class Company
{
private String name;
private String id;
private double money;
Company(){}
Company(String name,String id,double money){
this.name = name;
this.id = id;
this.money = money;
}

public void setName(String name){this.name=name;}
public void setId(String id){this.id=id;}
public void setMoney(double money){this.money=money;}
public String getName(){return name;}
public String getId(){return id;}
public double getMoney(){return money;}
public abstract void work();
}
//定义员工类
class Employee extends Company
{
Employee(){}
public void work(){
System.out.println("员工在写代码");
}
}
//定义经理类
class Manager extends Company
{
Manager(String name,String id,double money,double bonus){
super(name,id,money);
this.bonus = bonus;
}
private double bonus;
public void setBonus(double bonus){this.bonus=bonus;}
public double getBonus(){return bonus;}
public void work(){
System.out.println("经理指挥你写代码");
}
}
class AbstractTest2
{
public static void main(String[] args)
{
//创建员工类对象,调用set方法赋值
Company e = new Employee();
e.setName("张三");
e.setId("研发部001");
e.setMoney(10000.01);
e.work();
System.out.println(e.getName()+".."+e.getId()+".."+e.getMoney());

//创建经理类对象,构造方法直接赋值
e = new Manager("李四","董事会001",1234.56,567890.98);
e.work();
Manager m = (Manager)e;
System.out.println(e.getName()+".."+e.getId()+".."+e.getMoney()+".."+m.getBonus());
}
}


09.13_面向对象(抽象类中的面试题)

A:面试题1

一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?

可以

这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成

B:面试题2

abstract不能和哪些关键字共存

修饰符的冲突问题

final    抽象目的,子类重写,final不能重写
private  抽象目的,子类重写,但是子类不知道父类有这个方法
static   静态方法类名直接调用,如果是抽象没有方法体,怎么调用


09.14_面向对象(接口的概述及其特点)

A:接口概述

从狭义的角度讲就是指java中的interface

从广义的角度讲对外提供规则的都是接口

B:接口特点

a:接口用关键字interface表示

interface 接口名 {}

b:类实现接口用implements表示

class 类名 implements 接口名 {}

c:接口不能实例化

那么,接口如何实例化呢?

按照多态的方式来实例化。

d:接口的子类

a:可以是抽象类。但是意义不大。

b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

接口是一个对外暴露的规则

规定内容,并没有具体的实现

接口降低程序的耦合性(紧密连接),提高扩展性

面向接口编程

C:案例演示

接口特点

/*
定义接口,关键字interface
注意:修饰符,可写,不写,也可以选择性书写,任意写一个都行
编译的时候定义的是interface 编译器,检查,少哪一个,补充哪一个

*/
interface Inter
{
//定义接口成员变量
public  static final int I = 10;

//定义接口成员方法,全抽象
public  abstract void show();
}

class InterFaceDemo
{
public static void main(String[] args)
{
System.out.println();
}
}


09.15_面向对象(接口的成员特点)

A:接口成员特点

成员变量;只能是常量,并且是静态的。

* 默认修饰符:public static final

* 建议:自己手动给出。

构造方法:接口没有构造方法。

成员方法:只能是抽象方法。

* 默认修饰符:public abstract

* 建议:自己手动给出。

B:案例演示

接口成员特点

/*
定义接口,定义实现类,实现接口
创建实现类的对象
*/
interface Inter
{
public static final int I = 3 ;
public abstract void show();
public abstract void show2();
}
//定义接口实现类,实现接口重写抽象方法
class InterImpl implements Inter
{
public void show(){
System.out.println("实现类重写方法");
}
}
class InterFaceDemo
{
public static void main(String[] args)
{
InterImpl  impl = new InterImpl();
impl.show();
System.out.println(Inter.I); //常见调用方式
System.out.println(InterImpl.I);
System.out.println(impl.I);
}
}


09.16_面向对象(类与类,类与接口,接口与接口的关系)

A:类与类,类与接口,接口与接口的关系

a:类与类:

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

b:类与接口:

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

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

c:接口与接口:

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

B:案例演示

类与类,类与接口,接口与接口的关系

/*
接口的多实现
一个类,同时实现多个接口
多实现没有安全隐患的
但是方法没有主体,怎么运行,实现什么功能,完全由实现类自己说了算
*/
interface A
{
public abstract void a();
}
interface B
{
public abstract void a();
}
abstract class C
{
public abstract void c();
}
class D extends C implements A,B
{
public void a(){}
public void c(){}
}
class InterFaceDemo2
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}


/*
接口之间的多继承关系
*/
interface A
{
void a();
}
interface B
{
void b();
}
interface C extends A,B
{
void c();
}
class D implements C
{
public void a(){}
public void b(){}
public void c(){}
}
class InterFaceDemo3
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}


09.17_面向对象(抽象类和接口的区别)

A:成员区别

抽象类:

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

构造方法:有

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

接口:

成员变量:只可以常量

成员方法:只可以抽象

B:关系区别

类与类

继承,单继承

类与接口

实现,单实现,多实现

接口与接口

继承,单继承,多继承

C:设计理念区别

抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。

接口 被实现体现的是:”like a” 的关系。接口中定义的是该继承体系的扩展功能。

09.18_面向对象(老师和学生)

/*所有的东西都加上。(分析,实现,测试)
人类:姓名,年龄,吃饭,睡觉。
吸烟接口:吸烟
老师继承人类
学生继承人类
部分老师继承人类并实现吸烟接口
部分学生继承人类并实现吸烟接口

具体的事物
人: 属性成员变量,姓名年龄
人: 行为功能方法,吃饭睡觉

老师:属于人的一种,具备人的特性,继承人
老师的姓名和年龄,需要使用父类方法赋值
自己的特点,上课成功
老师:扩展出来的功能,吸烟

学生:属于人的一种,具备人的特性,继承人
学生自己的姓名和年龄,需要使用父类方法赋值
自己的功能学习

学生:扩展出来的,吸烟
is  a   老师和学生是人类中的一种
like a  老师和学生是人类中的一致,但是看上去更像烟民
*/
/*
定义人的抽象类
*/
abstract class Person
{
private String name;
private int age;
Person(){}
Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){this.name=name;}
public void setAge(int age){this.age=age;}
public String getName(){return name;}
public int getAge(){return age;}
//人类具备功能,吃饭,睡觉,写成抽象,子类实现,还是写好,子类调用
public abstract void eat();
public abstract void sleep();
}
/*
定义吸烟接口,谁吸烟,谁实现
*/
interface Smoking
{
public abstract void smoking();
}
//定义老师类,继承Person
class Teacher extends Person
{
//定义空参数构造
Teacher(){}
Teacher(String name,int age){
super(name,age);
}
//继承重写功能
public void eat(){
System.out.println("老师在吃饭");
}
public void sleep(){
System.out.println("老师在睡觉");
}
public void teacher(){
System.out.println("老师在上课");
}
}
//定义吸烟的老师,是人类一种,还吸烟
class SmokingTeacher extends Person implements Smoking
{
SmokingTeacher(){}
SmokingTeacher(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("吸烟的老师在吃饭");
}
public void sleep(){
System.out.println("吸烟的老师在睡觉");
}
public void teacher(){
System.out.println("吸烟的老师在上课");
}
public void smoking(){
System.out.println("老师下课在抽烟");
}
}
class  InterFaceTest
{
public static void main(String[] args)
{
Teacher t1 = new Teacher();
t1.setName("张三");
t1.setAge(35);
t1.eat();
t1.sleep();
t1.teacher();
System.out.println(t1.getName()+"..."+t1.getAge());

Teacher t2 = new Teacher("李四",43);
t2.eat();
t2.sleep();
t2.teacher();
System.out.println(t2.getName()+"..."+t2.getAge());

SmokingTeacher st1 = new SmokingTeacher("王五",20);
st1.eat();
st1.sleep();
st1.teacher();
st1.smoking();
System.out.println(st1.getName()+"..."+st1.getAge());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: