javase_07(继承与设计模式)

来源:互联网 发布:汉字翻译拼音软件 编辑:程序博客网 时间:2024/05/22 17:03

 子类对象的实例化过程:


     我们可以用一个类的变量记住它的子类的子类的实例.这时如果调用子类中的方法,只需要强制转换子类就可以
     没必要非得强制转换子类的子类.
     instanceof关键字:也可以判断子类实例也属于父类的类型

 

/*     子类对象的实例化过程     我们可以用一个类的变量记住它的子类的子类的实例.这时如果调用子类中的方法,只需要强制转换子类就可以     没必要非得强制转换子类的子类.     instanceof关键字:也可以判断子类实例也属于父类的类型. */  class A {     A()     {         //如果程序没有写构造方法的/java会默认给它添加构造方法!     }     public void a()     {             System.out.println("a() in A");     } }  class B extends A {     B()     {         super(); //默认调用父类的无参的构造方法!     }     public void a()     {             System.out.println("a()in B");     }      public void b()     {             System.out.println("b()in B");     }  }  class C extends B {     public void a()     {             System.out.println("a()in C");     }     public void b()     {             System.out.println("b()in C");     }     public void c()     {             System.out.println("C()int C");     } } class Demo  {     public static void main(String[] args)      {         A a = new C();         if(a instanceof C)         {             C c =(C)a;             c.c();         }         if(a instanceof B)         {             B b = (B)a;             b.b();         }     } }


 

  继承的细节:\


1.子类不会继承与父类的私有的成员
2.构造函数是不会被继承.
3.只支持单继承,可以多重继承.

  

/*    继承的细节.子类不会继承与父类的私有的成员.构造函数是不会被继承..只支持单继承,可以多重继承.    ------------------.以后在设计一个类的时候,父类一定要加上一个不带参数的super,否则子类实例化的时候会报错!    为什么有这样一个机制:    解答:别人来继承与这样一个类,一定也需要这个子类具有父类的方法.但是别人并不知道在构造函数里面做了一些特别才能实现这个    的功能.所以java就规定子类实例化的过程中.一定会默认调用与父类的super()的构造方法.如果你在父类中没有定义一个无参的.    那么在实例化的过程中是会容易出错的.*/class Person{    private String name ;    public Person(String name)    {        this.name = name;    }    public  Person()    {            //咱们加一个无参的构造方法!    }    public    void eat()    {            System.out.println("是人都要吃东西!");    }}class Student extends Person{        public Student()    {        //不带参数的构造函数!        super(); //默认为这个?  但是有这个父类的构造函数吗?显然没有对吧.。    }    public void eat()    {            System.out.println("抽一根");            super.eat();    }}class Demo {    public static void main(String[] args)     {        Student st = new Student();        st.eat();    }}


第三:

/*    子类的实例化过程:子类在创建做了什么事情呢?    解答:在创建子类的时候,会调用子类的构造函数,在子类构造函数的第一行会默认调用父类的构造函数                在子类构造函数中如果没有显式地调用父类的构造函数.它会自动的调用父类的无参的构造函数(在这个问题上你要注意)            我们可以在构造函数中使用this(实参)来调用自己的带参数的构造方法            还可以用super(实参)去调用父类型的带了参数的构造方法/            但要注意:this 与super()只能出现一次.  并且在第一行.            如果一个构造函数调用了this ,那么就不能从第二个语句使用super()*/class Person{    private String name ;    public Person()    {            System.out.println("无参的Person()被调用啦!");    }    public Person(String name )    {        this();        System.out.println("有参的Person()被调用啦!");        this.name = name;    }}class Student extends Person{    private String name;    public Student()    {            super("kudy");            System.out.println("无参的Student()被调用啦~");    }    public Student(String name)    {            this();  //与super()不能同时出现            System.out.println("有参的Student()被调用啦~");    }}class Demo {    public static void main(String[] args)     {        new Student("abc");    }}/*输出的结构为:--------------------------------无参的Person()被调用啦!有参的Person()被调用啦!无参的Student()被调用啦~有参的Student()被调用啦~*/


第四:多态

/*    关于多态:                不变应万变*/abstract class Person{    public abstract void eat();}class Chinese extends Person{    public void eat()    {            System.out.println("中国的人还是广东人最好啦!");    }}class Shop{    public void shopping(Person p )    {            System.out.println("咱们去买好东西吃!");            p.eat();    }}class Demo{    public static void main(String[] args)     {        Shop shop = new Shop();        shop.shopping(new Chinese());    }}


第五:面试题

/*    子类实例化的面试题!    A1 B2 B1*/class A{    String name = "张三";    public A()    {            System.out.println("A1");  //A1    }    public A(String name)    {        this();            System.out.println("A2");    }}class B extends A{    String name = "王五";    public B()    {             this("张");  //如果有了this 就是默认没了super()            System.out.println("B1");    }    public B(String name)    {    //    super();        System.out.println("B2"); //B2    }}class Demo {    public static void main(String[] args)     {        new B();    }}


第六:再讲多态

/*    覆盖父类的方法:    子类当中覆盖父类的方法必须要和父类具有相同的方法名,具有相同的参数类型,具有相同的返回值 返回值类型一定要和    子类的保持一直.这样就是方法的重写    子类的方法的权限不能比父类有更严格的访问权限,因为我们经常要把子类当做父类来使用.    子类去访问父类的方法时,会比较一下子类的访问权限.如果权限比父类小.那么就挂啦    多态: 把子类当做父类来使用,针对父类进行方法的调用.传入不同的子类.执行的结构是一样的.    除非父类被子类这个哥们重写啦方法~*/class Person{    public void run()    {            System.out.println("run() in Person");    }    public Person getInstance()    {            return new Person();    }}class Student extends Person{    public void run()    {            System.out.println("happy");            super.run(); //调用了父类的run方法!    }    public  Student getInstance() //权限不应该比父类的要小.  如果权限要比父类的小.那么就OH.Sorry    {        return new Student();    }}class Demo {    public static void main(String[] args)     {        Student stu = new Student();        stu.run();        run(stu);    }    //实现了多态!    public static void run(Person p )    {         p = p.getInstance();        p.run(); //实现了多态    }}


第七:final的应用:

/*final 关键字:最终的!终态的.被fina修饰的属性为常量,是不能被更改的.也就是说:值是不能被改变.final所修饰的方法不能被重写,也就是说不能被子类所覆盖.final修饰所修饰的类是不能被继承的!一般fina的用法:public static fina String NAME = "kudy"; 为什么它一般是和static一起的呢?解答:既然一个属性都不能被修改啦.是一个常量啦.咱们可以把他定义一个static的.在类出生的时候.它也会跟着出生.方便.*//*final class Person{    //被final所修饰的类是不能被继承的!}*/class Person{    public static final int NUM = 19 ;//给我修饰的常量是不能被修改的!    public final void show()    {            System.out.println("给我修饰的方法都是不能被重写!");    }}class Student extends Person{    /*    public void show()    {            System.out.println("真的是不能被重写噢!");    }    */    public void run (int num)    {        //先比较后自加!        System.out.println(++num);        System.out.println(num++);         //? 为多少呢?  20  //因为第一次自加1  后来第二次的时候。先输出值它自己再加1    }}class  Demo{    public static void main(String[] args)     {        Student stu = new Student();        stu.run(stu.NUM);    }}


设计模式:

组合

/*    设计模式!组合    组合:当一个对象在运作的过程中必须要用到另外一个对象的时候,然而又不是构成继承的关系的!*/class Guo{    public void heat()    {            System.out.println("已经自动的加热啦~");    }}class Chef{    //吃食品的时候一定要把它加热嘛~~    Guo guo;    Chef(Guo guo)    {        this.guo = guo;    }    public void cook()    {        guo.heat();    }}class Demo {    public static void main(String[] args)     {        Chef chef = new Chef(new Guo());        chef.cook();    }}


抽象类的简单使用:

/*    抽象类:.没有方法体必须要声明为abstract抽象方法.含有抽象方法的类一定是抽象类.抽象类的定义:用abstract修饰的类叫做抽象类.抽象类是不能被实例化的(也就是说不能创建对象!);.可以用一个抽象类来继承一个抽象类.会继承所有的方法.如果用一个类来继承抽象类,那么必须要实现抽象类里面所有的方法.抽象类的访问权限没有什么特殊之处.主要是看修饰符!.抽象类里面不一定有抽象方法.但是包含有抽象方法一定是抽象类*/abstract class A{    abstract void a();//抽象方法!    public void run()    {            System.out.println("A run()");    }}abstract class B extends A{    abstract void b();}class C extends B{    //必须要把它所继承的所有的抽象方法实现!    public void a()    {            System.out.println("A.class");    }    public void b()    {            System.out.println("B.class"); //实现B    }}class  Demo{    public static void main(String[] args)     {        A a = new C();        if(a instanceof C)        {            C c = (C)a;            c.a();            c.b();            c.run();        }    }}


模板方法的设计模式:

/*    模板方法的设计模式:    定义一个抽象类作为模板,将具体做事情方法定义出来,但是不实现.对外提供一个共有的方法作为接口,规定做事情的顺序/这个方法应该为final 避免了让子类重写    子类继承模板,实现所有的抽象方法()*/abstract class AbatractPrint{    abstract void opend();    abstract void print();    abstract void close();    //定义成终态的.避免了子类所修改!    public final void run()    {        this.opend();        print();        close();  //调用方法!    }}class StringPrint extends AbatractPrint{    private String data;    StringPrint(String data)    {        this.data = data;    }    public void opend()    {            System.out.print("<<");    }    public void print()    {            System.out.print(data);    }    public void close()    {            System.out.print(">>");    }}class Demo {    public static void main(String[] args)     {        AbatractPrint abatractPrint = new StringPrint("kudy");        abatractPrint.run();        //使用匿名内部类做一下这道题目!        //我现在不是为了抽象类创建对象.而是为了匿名子类!  //也多多态的一种形式!        //匿名内部类重写了父类的方法!并且调用一把run();        new AbatractPrint(){                public void opend()        {                System.out.print("<<");        }        public void print()        {                System.out.print("show");        }        public void close()        {                System.out.print(">>");        }        }.run();    }}



 

面向对象的例子:

//定义抽象类作为接口,实现个模块之间的解耦/*        首先第一种方法的:  显示就是三个人不能同时分工协作啦~~        咱们传入的时候要注意:  我们传入的是子类.  父类型的引用指向了子类型的对象。*///定义一个抽象的数据产生器!import java.io.*;abstract class Generator{    abstract String getData();}//定义一个抽象的数据处理器abstract class  DataHandler{    abstract String    handleData(Generator generator);}//甲负责写数据产生器class OneGenerator extends Generator{    public String getData()    {            return "hello";  //产生了一个数据!    }}//乙所负责写的数据处理代码class OneDataHandler extends DataHandler{    public String  handleData(Generator generator)    {        String data = generator.getData();        return  "~~"+data+"~~";     }}//数据产生器!class TwoGenerator extends Generator{    public String getData()    {        return "小细加油";    }}//数据处理器!class TwoDataHandler extends DataHandler{    public String     handleData(Generator generator)    {        String data = generator.getData();        return "~~~"+data+"~~~";    }}/*    数据显示!*/class Demo {    public static void main(String[] args) throws Exception    {        BufferedReader br                             = new BufferedReader(new InputStreamReader(System.in));        /*        DataHandler data = new OneDataHandler();        Generator gen = new OneGenerator();        */        //通过读取键盘获得用户使用的数据产生器名字        System.out.println("请输入您使用的数据产生器:");        String generatorClassName = br.readLine();        //根据类名反射出类        //Class class -->new Class()对象 --》class.Class        //1-1根据类名反射出类!        Class generatorClazz = Class.forName(generatorClassName);  //类        //又因为返回的是object 类型/所以我们要强制转换.否则没有办法赋值。        //根据类创建实例对象(数据产生器)         Generator  generator=( Generator) generatorClazz.newInstance(); //类创建对象。并且是父类型的引用指向子类型的对象。         //2.通过反射获得数据的处理器对象         System.out.println("请输入您要使用的数据处理器:");         String dataHandlerClassName = br.readLine();         Class dataHandlerClazz = Class.forName(dataHandlerClassName);         DataHandler dataHandler = (DataHandler)dataHandlerClazz.newInstance();        String data = dataHandler.handleData(generator);        System.out.println(data);    }}



 

原创粉丝点击