A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lyg0374 中级黑马   /  2016-8-2 07:24  /  274 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

------<a  target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -----------------**简述:**类(Class)实际上是对某种类型的对象定义变量和方法的原型。它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础。它为同一类的事物提供一个模板,比如人这个类就可定义人的基本特征,如状态量男、女;数值量身高、体重等;动作量走、跑、跳等,对于每个人来说就是人这个类的一个实体,是这个类的具体化,人和人之间的差距可以通过以上定义的量之间的不同来体现。**第一讲>>>>继承**注意:千万不要随便用继承,为了获取其他类的功能简化代码而继承,必须是累与类之间有所属关系才可以继承.所属关系 is a.Java语言中:java语言只支持单继承,不支持多继承.(并非多重继承).由于多继承容易带来安全的隐患.当多个父类中定义了多个相同的内容但内容不同时,要执行哪一个不确定!java虽然不支持多继承,但是java用了另一种体现方式来完成,叫做多实现.(借口).java支持多重继承,也就是一个继承体系.那么如何使用一个继承体系中的功能呢?想要使用体系,先查阅体系中父类的描述,因为父类中定义的是该体系中共性的功能,通过了解共性功能,就可以知道该体系的基本功能.那么这个体系这时候已经基本可以使用了.在具体调用时,要创建最子类的对象,因为        1. 有可能父类不能创建对象.        2. 创建自类对象是用更多的功能,包括基本的也包括特有的.简单一句话,查阅父类功能,创建子类对象使用功能.子父类出现后,类成员的特点:类中成员:1.变量.2.函数.3.构造函数.如果子类中出现非私有同名成员变量时,子类要访问同类中的变量,用this,父类则用super.super是用方法同this.子类中同名于父类函数的特点:重写(覆盖)(非重载).记住:重载:只看同名函数的参数列表类型个数.重写:子父类方法要一模一样.(参数类型个数必须相同!)用子类继承父类,沿袭了父类的功能,到子类中,但是子类虽然具备该功能,但是功能却跟父类不一致,这时没有必要定义新功能.而是使用覆盖原父类中的函数.,保留父类中功能的定义,并重写功能内容.覆盖:子类覆盖父类,必须保证子类权限大于等于父类,才可以覆盖,否则编译失败.静态只能覆盖静态.**子父类中的构造函数**构造函数随着类名走,类名不能相同.因此子类构造函数不能继承父类构造函数.但是创建子类对象时会调用父类的构造函数(在子类的构造函数第一行有隐式的super()父类构造函数).为什么子类一定要访问父类中的构造函数:子类创建时,父类中的数据子类可以直接获取,所以在子对象建立时,需要先看看父类是否对这些数据进行初始化,如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定.注意:super语句一定定义在子类构造函数的第一行.子类的实例化过程结论:子类的所有的构造函数默认都会访问父类的空参的构造函数,因为每一个子类构造函数内第一行都有一句隐式的super();当父类中没有空参数的构造函数时,子类必须手动通过super或者this形式访问指定的父类中的构造函数.当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数.子类中至少有一个构造函数会访问父类中的构造函数.**Final**Final:最终,作为一个修饰符.        * 可以修饰类,变量,函数.        * 被final修饰的类不能被继承.为了避免被继承,被子类复写功能.        * 被final修饰的方法不可以被复写(重写).        * 被final修饰的变量是一个常量只能被复制一次,既可以修饰成员变量,也可以修饰局部变量.        * 内部类定义在类中的局部位置上是,只能fangwen该局部final修饰的局部变量.当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字,方便于阅读.而这个值不需要改变,所以加个final修饰不允许改变.作常量是用.常量的书写规范所有的字母都大写,如果多个单词组成,则单词间通过"_"连接.        * 内部定义类在类中的局部位置上时,只能访问该局部被final修饰的局部变量.**抽象类**当多个类中定义相同的功能,但是功能主题不同,这时可以进行向上抽取,只抽取功能定义,而不抽取功能主体.抽象类的特点:        1. 抽象方法必须存在于抽象类中.        2. 抽象方法和抽象类都必须被abstract关键字修饰.        3. 抽象类不可以用new问问创建对象,因为调用抽象方法没有意义.        4. 抽象类的方法要被使用,必须由子类复写所有抽象方法,建立子类对象调用.如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类.        5. 抽象类比一般类多了抽象方法.可以在类中定义抽象方法,在抽象类中可以定义非抽象方法.此时可防止创建该类的对象.不可以实例化.抽象类和一般类没有太大区别,描述事物的方式也一样.不过对于事物中不确定的部分,需要通过重载明确出现,因此不定义主体.```abstract class Employee{        private String name;        private String id;        private double pay;        public Employee(String name, String id, double pay) {                super();                this.name = name;                this.id = id;                this.pay = pay;        }        public abstract void work();        //由于不同的雇员,所做的工作不同,因此这个方法定义为抽象方法.        //方便不同员工种类从这个雇员类继承,有了几个成员变量的同时,也可以实现各自的工作方式.}```另一方面,我们讲一下模板方法设计模式:```class GetTime{        public void getTime(){                long start = System.currentTimeMillis();                                for (int i = 0; i < 100; i++) {                        System.out.println("code run");                }//粗略计算这段代码所运行的时间                                long end = System.currentTimeMillis();                        }}class TemplateDemo{        public static void main(String[] args) {                GetTime gt = new GetTime();                gt.getTime();        }}```所需要计算运行时间的代码可以封装到一个方法中,这样方便与于我们对程序进行扩展.代码如下:```class GetTime{        public void getTime(){                long start = System.currentTimeMillis();                                runcode();                                long end = System.currentTimeMillis();                        }        private void runcode() {                // TODO Auto-generated method stub                for (int i = 0; i < 100; i++) {                        System.out.println("code run");//封装了所需要计算运行时间的代码,程序看起来更加明了,想要计算新的代码的运行时间只需更新这段代码即可!                }        }}```现在,可以继承该类,复写runcode,即可获取代码运行时间!此时将getTime()命名为final类即可避免子类复写getTime()函数.这类设计方式成为模版方法设计模式.提高了扩展性和复用性!什么是模板方法呢?在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴漏出去,由该类的子类去完成这个功能.**第二讲>>>接口**初期理解可以认为是一特殊的抽象类,当抽象类的方法都是抽象的,那么该类可以通过接口的形式来表示.接口定义时,格式特点:        1. 接口中常见定义:常量,抽象方法.        2. 接口中的成员都有固定修饰符.                1. 常量:public static final                2. 方法:public abstract实现,代码中的关键字为implements.例如class subInter implements Interface由于有抽象方法,接口不可以创建对象需要被子类实现,子类对接口的抽象方法全部都覆盖后,子类才可以实例化.否则子类是一个抽象类.接口可以被类多实现.(一个类可以同时实现多个接口).也是对不支持多继承的弥补. **1. 类与类之间继承关系.**  **2. 类与接口是实现关系.**  **3. 接口与接口之间是继承关系.**```//A B两接口中有两个变量类型不同,函数名相同的方法,这样C继承了A B,是不允许的.//当父类中有一些功能子类不需要的时候,可以把那些不需要的功能另外定义一个接口.即:基本功能定义在父类中,扩展功能定义在接口中.interface A{        void methodA();        int show();}interface B{        void methodB();        boolean show();}interface C extends B,A{        void methodC();}class D implements C{        public void methodA(){}        public void methodC(){}        public void methodB(){}        public int show(){}        public boolean show(){}}```**第三讲>>>多态**可以理解为事物存在的多种体现形态.人        <--------------男人--------------        女人或者说动物<------------猫----------------狗建立对象时我们可以:猫 X = new 猫();动物 x = new 猫();        1. 多态的提现                1. 父类的引用指向了自己子类的对象.                2. 父类的引用也可以接受自己的子类对象.        2. 多态的前提                1. 必须是类与类之间的关系,要么继承,要么实现.                2. 通常还有一个前提,存在覆盖.        3. 多态的优点        多态的出现大大提高了程序的扩展性.        1. 多态的弊端        提高了扩展性,但是只能是用父类的引用访问父类的成员.        4. 多态的应用        ```package test1;public class DuotaiDemo {                public static void main(String[] args) {//                        fun(new Cat());                        Animal an = new Cat();                        Cat c = (Cat)an;//向下转型                        c.mouse();                        DoS d1 = new DoS();                        d1.fun(new Cat());                }                }class DoS{        public static void fun(Animal a) //向上转型        {                a.eat();                if(a instanceof Cat)                {                        Cat c = (Cat)a;                        c.eat();                }                else if(a instanceof Dog)                {                        Dog d = (Dog)a;                        d.eat();                }        }}interface Animal{        void eat();        void mouse();}class Cat implements Animal{        public void eat()        {                System.out.println("fish");        }        public void mouse()        {                System.out.println("Mouse");        }}class Dog implements Animal{        public void eat()        {                System.out.println("bone");        }        public void mouse()        {                System.out.println("NONONO");        }}```那么在多态的使用中,我们会遇到这样的问题:创建一个对象的时候,方法是属于左边,还是右边呢?在多态中成员函数的特点:        重点:在编译时期,参阅引用型变量所属的类中是否有调用的方法.如果有,编译通过,如果没有编译失败.        * 在运行时期:参阅对象所属的类中是否有调用的方法.        * 简单总结下就是:成员函数在多态调用的时候,编译看左边,运行看右边.        * 在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属类).        * 在多态中,静态成员函数的特点:编译,运行的时候都参考左边.多态的主板示例:电脑运行实例:电脑运行基于主板.```package test1;public class DuotaiDemo3 {        public static void main(String[] args) {                // TODO 自动生成的方法存根                Mainboard mb = new Mainboard();                mb.run();                mb.usePCI(new Cpu());        }}interface PCI{        void open();        void close();}class Mainboard{        public void run()        {                System.out.println("zhuban run");        }        public void usePCI(PCI p)        {                if(p!=null)                {                        p.open();                        p.close();                }        }}class Cpu implements PCI{        public void open()        {                System.out.println("Cpu run");        }        public void close()        {                System.out.println("Cpu boom");        }}**第四讲>>>内部类,匿名内部类**内部类的访问规则:  内部类可以直接访问外部类中的成员,包括私有成员.之所以可以直接访问外部类中的成员,是in为内部类持有了一个外部类的引用,格式为:外部类名.this.外部类要访问内部类必须建立内部类对象.```package test1;public class InnerClassDemo {        public static void main(String[] args) {                // TODO 自动生成的方法存根                Outer o = new Outer();                o.method();//                Outer.Inner oi = new Outer().new Inner();                //建立内部类对象的时候的固定格式                new Outer.Inner().func();//当内部类为静态的时候,调用格式        }}class Outer{        int x = 3;        static class Inner //inner class 可以被private,static修饰        {                int x = 5;                void func() //static时,则内部类必须是static的                {//当外部类中的静态方法访问内部类的时候,内部类也必须是静态的.                        int x = 6;                        System.out.println("inner class:"+x);                }// Inner.this.x 5  Outer.this.x 3   x 6        }        void method()        {//                Inner in = new Inner();//                in.func();        }}```访问格式:当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中.可以直接建立内部类对象.格式为:外部类名.内部类名对象名 = 外部类对象.内部类对象(new外部类().new内部类()).当内部类在成员位置上,就可被成员修饰符修饰,比如private,将内部类在外部类中进行封装.Static:内部类就具备了静态的特性,可以直接被外部类对象调用.当内部类被static修饰后,只能直接访问外部类中的静态成员,出现了访问限制.在其他外部类中,如何直接访问内部类中的非静态成员呢?New Outer.Inner().function();在其他外部类中,如何直接访问内部类中的静态成员呢?Outer.Inner.function();注:当内部类中定义了静态成员,该内部类必须是静态的!当外部类中的静态方法访问内部类时,内部类必须是static的.当描述事物时,事物的内部还有事物,该事物用内部类来描述.因为内部事物在使用外部事物的内容.局部内部类不能定义静态成员,也不能用private修饰.内部类定义在局部时,不可以被成员修饰符修饰,可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问它所在的局部中的变量,只能访问被final所修饰的局部变量.匿名内部类匿名内部类,就是内部类的简写格式.定义匿名内部类的前提:内部类必须是继承一个类(这个类须是外部类)或者实现接口.匿名内部类的格式:        new 父类或者接口()        {                定义子类的内容        }        例如`                new Object()                {                        void func()                        {                                System.out.println("aa");                        }                }.func();;        }`其实匿名内部类就是一个匿名子类对象 ,而且这个对象有点胖,可以理解为带内容的对象.但是每次调用匿名对象完了以后,想要再次使用匿名类的功能,就需要重新建立一个对象.当匿名内部类继承的类,是抽象类且抽象方法很多,非常麻烦.内部类有时候是方便的,注意使用会方便我们写代码.

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马