必赢亚洲手机app下载


草根说70:回收站

叁G知识入门讲座

java-多态-object

概要图

必赢亚洲手机app 1

一 多态

一.1 多态的爆发

下边的 深草绿部分下跌了代码的可扩充性

    Dog d = new Dog();
        method(d);

        Cat c = new Cat();
        method(c);
    }

    //接收Dog,让dog做事。
    public static void method(Dog d)
    {
        d.eat();
    }
    //接收Cat,让cat做事。
    public static void method(Cat c)
    {
        c.eat();
    }

 

对其修正 见上边灰白部分

//多态技术的引出。解决什么问题?程序扩展性的问题。

//描述Dog
class Dog extends Animal 
{
    public void eat()
    {
        System.out.println("骨头");
    }
    public void lookHome()
    {
        System.out.println("看家");
    }
}

//描述猫
class Cat extends Animal 
{
    public void eat()
    {
        System.out.println("鱼");
    }
    public void catchMouse()
    {
        System.out.println("抓老鼠");
    }
}
//进行抽取。将共性的功能抽取到父类Animal中。
abstract class Animal
{
    public abstract void eat();
}

class DuoTaiDemo
{
    public static void main(String[] args) 
    {
        Dog d = new Dog();
//        d.eat();
        method(d);

        Cat c = new Cat();
        method(c);
    }
    /*
    发现,每多一个动物,都需要为这个动物单独定义一个功能,
    让这个动物的对象去做事。
    这个程序扩展性就很差。
    如何提高这个扩展性呢?
    发现既然是让动作去eat,无论是dog,还是cat,
    eat是它们共性,干脆,将eat进行抽取。抽取到父类Animal中。

    Dog是Animal中的一种。
    Dog d = new Dog();
    Animal a = new Dog();
    Cat c = new Cat();
    Animal aa = new Cat();
    */
    //只要建立animal的引用就可以接收所有的dog cat对象进来。让它们去eat。
    //提高了程序的扩展性。
    public static void method(Animal a)
    {
        a.eat();
    }

    /*
    //接收Dog,让dog做事。
    public static void method(Dog d)
    {
        d.eat();
    }
    //接收Cat,让cat做事。
    public static void method(Cat c)
    {
        c.eat();
    }
    */

}

 

必赢亚洲手机app,1.二 多态的有个别标题

【体现】
父类的引用大概接口的引用指向了和煦的子类对象。
Dog d = new Dog();//Dog对象的连串是Dog类型。
Animal a = new Dog();//Dog对象的门类右侧是Dog类型,左侧Animal类型。
【好处】
升高了先后的扩充性。
【弊端】
通过父类引用操作子类对象时,只可以利用父类中已有的艺术,不能够操作子类特有的秘籍。

子类是父类的对象,父类不是子类的目的
【前提】
一,必须有涉嫌:承继,实现。
贰,平日都有重写操作。
【子类的有意方法怎么着调用呢?】
Animal a = new Dog();//Animal是父类型,new Dog()是子对象。
唯独父类型引用指向子类对象时,那正是让子类对象开展了类别的晋升(向上转型)。
进步转型好处:进步了增添性,隐藏了子类型。弊端:不能够采用子类型的特有方法。
假如要想选用子类的特有方法,唯有子类型能够用。
可以向下转型,强制调换。
Animal a = new Dog();
a.eat();
Dog d = (Dog)a;//将a转型为Dog类型。向下转型。
d.lookHome();
向下转型何时用?当须要使用子类型的特有内容时。

在意:无论向上依然向下转型,最终都是子类对象做着品种的变迁。

【向下转型的注意事项】
Animal a = new Dog();
//Cat c =
(Cat)a;向下转型因为不精通具体子类对象类型,所以轻松引发ClassCastException分外。(代码上边深铁锈色)

public class Test {

    public static void main(String[] args) 
    {
        Dog d = new Dog();  
        method(d);
        Cat c = new Cat();
        method(c);
    }
    public static void method(Animal a)
    {

        a.eat();
        Dog d = (Dog)a;
        d.lookHome();
    }

}
class Dog extends Animal 
{
    public void eat()
    {
        System.out.println("骨头");
    }
    public void lookHome()
    {
        System.out.println("看家");
    }
}

//描述猫
class Cat extends Animal 
{
    public void eat()
    {
        System.out.println("鱼");
    }
    public void catchMouse()
    {
        System.out.println("抓老鼠");
    }
}
//进行抽取。将共性的功能抽取到父类Animal中。
abstract class Animal
{
    public abstract void eat();
}

Exception in thread “main” 骨头
看家

java.lang.ClassCastException: test.Cat
cannot be cast to test.Dog

 

 

由此为了防止那些主题素材,必要在向下转型前,做项目标论断。
决断项目用的是入眼字 instanceof

if(a instanceof Cat)//a指向的对象的类型是Cat类型。
{
//将a转型Cat类型。
Cat c = (Cat)a;
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog d = (Dog)a;
d.lookHome();
}

 

【转型总括】
一,哪天利用向上转型呢?
抓实程序的扩充性,不关乎子类型(子类型被埋伏)。
亟待用子类的蓄意方法吗?不须要,哦了。向上转型。
二,哪天利用向下转型呢?
内需使用子类型的特有方法时。
唯独毫无疑问要采取 instanceof 进行项目标推断。幸免发出 ClassCastException

壹.三 多态的事例

率先个例证

class 毕姥爷
{
    public void 讲课()
    {
        System.out.println("讲管理");
    }
    public void 钓鱼()
    {
        System.out.println("钓鱼");
    }
}

class 毕老师 extends 毕姥爷
{
    public void 讲课()
    {
        System.out.println("Java");
    }
    public void 看电影()
    {
        System.out.println("看电影");
    }
}


class DuoTaiTest 
{
    public static void main(String[] args) 
    {
        毕姥爷 x = new 毕老师();//多态,向上转型。
        x.讲课();
        x.钓鱼();
//        x.看电影();//不行。
        //想要使用毕老师的特有方法时,需要向下转型。
        if(x instanceof 毕老师)
        {
            毕老师 y = (毕老师)x;
            y.看电影();
        }
        //自始至终都是子类对象做着类型的变化。


    }
}

 

 留意:无论向上依然向下转型,最终都以子类对象做着项目标变迁

第1个例证

/*
品级一供给:台式机计算机运行。
依据面向对象的构思,用代码呈现。
名称提炼法
台式机电脑。
行为:运行。

class NoteBook
{
//运行功能。
public void run()
{
System.out.println("notebook run");
}
}

 

 等第二必要:想要在台式机Computer上增多三个手握式鼠标。
多了个对象:鼠标。
行为:开启,关闭。

class Mouse
{
public void open()
{
System.out.println("mouse open");
}
public void close()
{
System.out.println("mouse close");
}
}

台式机怎么用鼠标呢?
在记录本中多2个用到鼠标的功用。
亟需修改原来的台式机类中的内容,增多3个职能。

这般的做法也正是把台式机张开,把鼠标焊到里面

因为她间接在改原代码

class Mouse
{
public void open()
{
System.out.println("mouse open");
}
public void close()
{
System.out.println("mouse close");
}
}

 

public class Test {




    public static void main(String[] args) 
    {
        NoteBook n =new NoteBook();
        n.run();
        n.userMouse(null);

    }


}
class NoteBook {
    public void run (){
        System.out.println("notebook run");
    }
    public void userMouse(mouse m){
        if(m!=null){

            m.open();
            m.close();
        }

    }
}
class mouse {
    public void open (){
        System.out.println("mouse open");
    }
    public void close (){
        System.out.println("mouse close");
    }

}

结果 notebook run

 

//难点:假若想要插足三个键盘呢?
如若描述2个键盘类,并在管理器类中参预二个行使键盘的作用就哦了。
不过发掘从鼠标开端这一个问题就已经发生了,一旦供给增多新装置的时候,
都必要改动计算机的源码。这几个扩张性是万分差的。

统一筹划上该怎么创新呢?
事先的难题在于外围设备的加码和台式机计算机之间的耦合性过高。
怎么下降外围设备和台式机计算机的耦合性呢?
外围设备还不明显,大家绝不面对外界具体设备。
为了让台式机能够动用那个设施,能够优先定义好有的规则,
台式机只要采纳那些规则就可以了。
有了那个规则就能够进行台式机的成效扩充。
末代那个外围设备只要符合这么些规则就足以被台式机使用了。

那么规则在java中该怎样显示吗?接口

//一,描述接口。USB。

//二,描述台式机Computer:启动作效果果,使用USB接口的效应。

*/
//USB接口定义。
interface USB
{
void open();
void close();
}

//描述笔记本电脑。 
class NoteBook
{
public void run()
{
System.out.println("notebook run");
}

//使用usb接口的功能。
public void useUSB(USB usb)//接口类型的变量。接口类型的变量指向自己的子类对象。
//USB usb = new Mouse();
{
if(usb!=null)
{
usb.open();
usb.close();
}
}
}
//需要鼠标 。想要被笔记本电脑使用,该鼠标必须符合规则。
//描述鼠标。
class Mouse implements USB
{
public void open()
{
System.out.println("mouse open");
}
public void close()
{
System.out.println("mouse close");
}
}

class KeyBoard implements USB
{
public void open()
{
System.out.println("KeyBoard open");
}
public void close()
{
System.out.println("KeyBoard close");
}
}

/*
发现,接口的出现,
1,扩展了笔记本电脑功能。
2,定义了规则。
3,降低了笔记本电脑和外围设备之间的耦合性。
*/

class DuoTaiTest2 
{
public static void main(String[] args) 
{
NoteBook book = new NoteBook();
book.run();
book.useUSB(null);
book.useUSB(new Mouse());
book.useUSB(new KeyBoard());
}
}

一.四 多态中成员调用的特点。

一,成员变量
当子父类中冒出同名的积极分子变量时。
多态调用该变量时:
编写翻译时代:参考的是引用型变量所属的类中是还是不是有被调用的分子变量。未有,编写翻译退步。
运作时代:也是调用引用型变量所属的类中的成员变量。
轻松记:编写翻译和周转都参照等号的左手。
编写翻译运转看右边。

 

贰,成员函数。
编写翻译,参考左侧,借使未有,编写翻译退步。
运转,参考左边的靶子所属的类。
编写翻译看左侧,运转看左边。

能够当做是办法的重写.当然要运转右侧了
对于成员函数是动态绑定到对象上。(动态是指目的不明确)

三,静态函数。
编写翻译和平运动作都参照右边。

也能够用作是重写.按理说应该是和地点的积极分子函数是二个结果的,然则静态函数是与目的非亲非故的,

故此运转的是左手Fu 的method,只和调用者有提到

静态函数是静态的绑定到类上。(静态 是指在尤其类中)

上面深藕红部分

package test;

public class Test {




    public static void main(String[] args) 
    {
        Fu f = new Zi();
        System.out.println(f.num);// 3
        f.show();  // zi show run..
        f.method(); // fu static method run

    }


}
class Fu
{
    int num = 3;

    void show()
    {
        System.out.println("fu show run");
    }
    static void method()
    {
        System.out.println("fu static method run");
    }
}
class Zi extends Fu
{
    int num = 5;

    void show()
    {
        System.out.println("zi show run..");
    }
    static void method()
    {
        System.out.println("zi static method run");
    }
}

 

【结论】
对此成员变量和静态函数,编写翻译和平运动作都看右边。 
对于成员函数,编写翻译看左边,运维看左边。

二 object

2.一 object 常用艺术

API(应用程序接口(接口:指的是有的共用的事物))文 档

/*
Object类中的常用方法

Object类是全部类的根类,定义了具备目的都负有的效劳。
API(应用程序接口)文书档案

*/

class Person extends Object
{
private int age;
Person(int age)
{
this.age = age;
}

//决断是不是是同龄人。这一个措施也是在可比四个person对象是还是不是等于。
//注意:Person类中是还是不是有比较多少个Person对象相等的措施?有的!因为承继Object,它自个儿就具有着equals方法。
//既然有,还亟需定义compare方法吗?不要求。
//可是,equals方法推断的是地点,不是大家所要求的剧情。
//咋做?继续采纳Object的equals方法,可是建立子类的谐和的内容。传说中的重写。
【记住:现在推断目的是还是不是一样,就供给覆盖equals方法。】

重写equals 

注意: 

1 参数是object obj

二 要向下转型

public boolean equals(Object obj)
{

//建立Person自己的判断相同的依据。判断年龄是否相同。
//    return this.age == obj.age;//obj所属类型Object,Object中没有定义age,所以编译失败。

//如果调用该方法的对象和传递进来的对象是同一个。就不要转型和判断,直接返回true。效率高一点。
if(this == obj)
return true;

//age是Person类型的属性。既然要用到子类型的内容,需要向下转型。
if(!(obj instanceof Person))
//    return false;
throw new ClassCastException("类型是不对的!请改正。");
Person p = (Person)obj;

return this.age == p.age;

}

 

 重写toString 

//覆盖toString方法,建立Person对象自己的字符串表现形式。
public String toString()
{
return "Person[age = "+age+"]";
}

 三 习题

1,描述图书:book  
    作者,书名,价格。
    行为:6个set get
    建立book比较相同的依据。只要书名相同就视为同一本书。  
    字符串判断相同:请查api文档。equals方法,String类重写Object类中的equals
    建立book对象的字符串表现形式。 Book[作者:+  书名 +  价格]


2,写出结果。如果编译失败,请注明原因。

class Super
{
    int i=0;
    public Super(String a)
    {
        System.out.println("A");
        i=1;    
    }
    public Super()
    {
        System.out.println("B");
        i+=2;
    }
}
class Demo extends Super
{
    public Demo(String a)
    {//super();
        System.out.println("C");
        i+=5;                
    }
    public static void main(String[] args)
    {
        int i=4;
        Super d=new Demo("A");
        System.out.println(d.i);
    }
}
//B C 7

3.
选择题,写出错误答案错误的原因,用单行注释的方式。
class Demo
{
     int show(int a,int b){return 0;}
}
下面那些函数可以存在于Demo的子类中。    
A.public int show(int a,int b){return 0;}//    可以的,重写了。权限大于父类方法权限。
B.private int show(int a,int b){return 0;}// 不可以的,要重写,但是权限不够。
C.private int show(int a,long b){return 0;}// 可以。相当于重载。
D.public short show(int a,int b){return 0;}// 不可以的。调用的不确定性。
E.static int show(int a,int b){return 0;}//    不可以的,static只能重写静态。


4,
写出程序结果,如果编译失败,请注明原因。

interface A{}
class B implements A
{
    public String test()
    {
        return "yes";
    }
}
class Demo
{
    public static A get()
    {
        return new B();
    }
    public static void main(String[] args)
    {


        A a=get();
        System.out.println(a.test());//编译失败,因为a所属的A接口中没有Test()方法。
//        A a = new B();相当于这句。
//        a.test(); 是多态调用不?是!test()是非静态成员函数不?是! 规律:编译看左边,有吗?没有,所以编译失败。

 

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图