黑马程序员----JAVA 之 面向对象

---------------------- android培训 、 java培训 、 期待与您交流! -----------------


类和对象的关系:

    类:对现实生活中事物的描述。
    对象:就是一类事物实实在在存在的个体。


对象(即为引用)在栈内存中。new的时候在栈内存中开辟空间,类中的属性跟方法存在栈内存中,且不存在引用。
属性在堆内存中:堆中都有默认初始化。
成员变量作用于整个类中;局部变量作用于函数中,或者语句中。
在内存中的位置:
    成员变量:在堆内存中,因为对象的存在,才在内存中存在,有初始化值。
    局部变量:存在栈内存中,没有初始化。

匿名对象的使用:
    1、当对象的方法只调用一次时,可以用匿名对象来完成,如果对一个对象进行多个成员调用,必须给这个对象起个名字。
    2、可以讲匿名对象作为参数传递。

做缓存的时候要考虑:强引用,弱引用,软引用,区引用。

面向对象的三个特性:封装(Encapsulation),继承,多态。
封装:隐藏对象的属性跟实现细节,仅对外提供公共访问方式。之所以对外提供访问方式,就是因为可以在访问方式中加入判断语句,提高代码健壮性。
    当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数。当自定义了构造函数时,系统就不在默认加构造函数。
    构造函数在对象一建立时就调用,给对象初始化,构造函数只运行一次;一般方法在对象调用时才执行,可以被对象多次调用。

    this代表他所在函数所属对象的引用。(即:哪个对象在调用this所在函数,this就代表哪个对象)

    this的两种应用:

            1、区分同名变量的情况:区分当定义类中功能时,该函数内部要用到调用该函数的对象时,这是用this来表示这个对象。但凡本类功能内部使用了本类对象,都用this表示。

            2、this语句:用于构造函数之间进行互相调用。
            this语句只能定义在构造函数的第一行,因为初始化要先执行。
        

继承:

    1、提高了代码的复用性。

    2、让类与类之间产生了关系。有了这个关系才有了多态的特性。
         注意:不能为了简化代码而继承,必须是类与类之间的所属关系才可以继承。 所属关系即为 is a .
    
         java中只支持单继承,不支持多继承,因为多继承容易带来安全隐患,当多个父类中定义了相同的功能,当功能内容不同时,子类对象不确定要运行哪一个。
        java支持多层继承,亦一个继承体系。
        如何使用一个继承体系中的功能?想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
        想了解共享功能,就可以知道该体系的基本功能。那么这个体系就可以基本使用了。
        简单的说:查阅父类功能,创建子类对象使用。
    
    如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;子类要访问父类中的同名变量,用super.

    覆盖:

        1、子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。

        2、静态只能覆盖静态(静态先加载)。


       重载:只看同名函数的参数列表。
       重写:子父类方法要一模一样。
    
    子父类的构造函数:
        在堆子类对象进行初始化时,父类的构造函数也会运行,并且会先运行,因为子类的构造函数默认第一行有一条隐士的语句super();
        super会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super().
        子类一定要访问父类中的构造函数,如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
        super语句一定要定义在子类构造函数的第一行。
        子类的实例化过程:子类的所有构造函数,默认都会访问父类中空参数的构造函数。
        当父类中没有空参数的构造函数时,子类必须手动通过super或者this语句形式来指定要访问的构造函数。

多态:        
    多态的体现:父类的引用指向了自己的子类对象;父类的引用也可以接受自己的子类对象。
    多态的前提:必须是类于类之间的关系;要么继承,要么实现。通常还有一个前提:存在覆盖。
    多态的好处:多态的的出现大大提高了程序的扩展性。
    多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员。
    在多态中,非静态成员函数的特点(父子类):
        在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有编译通过,没有则失败。
        在运行时期:参阅对象所属的类中是否有调用的方法。
        简单说:成员函数在多态调用时,编译看左边,运行看右边。
    在多态中,成员变量的特点:
        无论编译和运行,都参考左边。
        
final:
    1、可以修饰类,函数,变量。
    2、被final修饰的类不可以被继承,为了避免被继承,被子类复写功能。
    3、被final修饰的方法不能被覆写。
    4、final修饰的变量是一个常量,只能赋值一次,即可以修饰成员变量,也可以修饰局部变量。 常量的书写所有字母都大写,如果由多个单词组成时,通过“_”连接。
    5、内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
    
抽象类:
    当多个类中出现相同功能,但是功能主体不同,可以向上抽取。这时,只抽取功能定义,而不抽取功能主体。
    抽象类的特点:
        1、抽象方法一定在抽象类中。
        2、抽象方法和抽象类都必须被abstract关键字修饰。
        3、抽象类不可以用new创建对象,因为调用抽象方法没有意义。
        4、抽象类中的方法要被调用,必须由子类复写所有的抽象方法后,才能建立子类调用。
            如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
        抽象类中可以不定义抽象方法。

模板方法:在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,
    那么这时就将不确定的部分暴露出去,由该类的子类去完成,可以定义成抽象的,但是不一定是抽象的 。
    
接口(interface):
    接口定义特点:
        1、接口中常见定义:常量,抽象方法。
        2、接口中成员有固定修饰符,如果不写则给补上。
            常量:public static final.
            方法:public abstract.
    接口中的成员都是public。
    接口不能创建对象,因为有抽象方法。
    子类必须对接口中的抽象方法全部覆盖后,子类才可以实例化。否则,子类是一个抽象类。
    接口的特点:
        接口是对外暴露的规则。
        接口是程序的功能扩展。
        接口可以被多实现。
        类与接口之间是实现关系,一个类可以继承一个类的同时实现多个接口。
        接口间可以有继承关系:即interface B extends A 。 或者interface C extends B,A 。只有在接口与接口之间存在多继承,类之间只能存在单继承。
     基本功能写在类中,扩展功能写在接口中。
    
static关键字:
    static是一个修饰符,用于修饰成员(成员变量和成员函数)。
    具有以下特点:
        1、随着类的加载而加载,随着类的消失而消失,生命周期最长。
        2、优先于对象存在---静态先存在,对象后存在。
        3、被所有对象所共享。
        4、可以直接被类名调用。即:类名.静态成员。
    使用注意:
        静态方法只能访问静态成员
        静态方法中不可以写this,super关键字--因为静态优先于对象存在。
    实例变量和类变量的区别:
        类变量随着类的加载而存在于方法区中。
        实例变量随着对象的加载存在于堆内存中。
    静态的利弊:
        利:对对象的共享数据进行单独空间的存储,节省空间;可以直接被类名调用。
        弊:生命周期过长;访问出现局限性(静态只能访问静态)。
    什么时候定义静态变量呢?当对象中出现共享数据时,该数据被静态所修饰。
    什么时候定义静态函数呢?当功能内部没有访问到非静态数据(对象的特有数据)时,那么该功能可以定义成静态的。
    静态代码块:
        格式:
        static
        {
            静态代码块中的执行语句。
        }
        特点:随着类的加载而执行,只执行一次,并优先于主函数 。用于给类进行初始化的。
        看下下边的代码:
     
  class StaticCode{
            Static{
                System.out.println("a");
            }
        }
        class StaticCodeDemo{
            static{
                System.out.println("b");
            }
            public static void main(String[] args){
                new StaticCode();
                new StaticCode();
                System.out.println("over");
            }
            static{
                System.out.println("c");
            }
        }


        此段代码的输出为: b c a over.
      
 class StaticCode{
            StaticCode(){
                System.out.println("b");
            }
            StaticCode(int x){
                System.out.println("d");//为对应对象初始化
            }
            {
                System.out.println("c"); //为对象初始化
            }
            static{
                System.out.println("a"); //静态代码块为类初始化
            }
        }
        class StaticCodeDemo{
            public static void main(String[] args){
                new StaticCode(4);
            }
        }

        代码的打印结果为:a c d


        StaticCode sc = new StaticCode();这句话在内存中做了什么事情呢?
            1、因为new用到了StaticCode.class,所以会先找到StaticCode.class文件并加载到内存中。
            2、执行该类中的static代码块,如果有的话,给StaticCode.class类进行初始化。
            3、在堆内存中开辟空间,分配内存地址。
            4、在堆内存中建立对象的特有属性,并进行默认初始化。
            5、对属性进行显示初始化。
            6、对对象进行构造代码块初始化。
            7、对对象进行对应的构造函数初始化。
            8、将内存地址赋给栈内存中的sc变量。
        程序运行的时候分为:栈内存、方法区、堆内存。
        
设计模式:解决某一类问题最行之有效的方法。
    java中有23种设计模式。
    单例模式:(具体代码请参考JAVA 之多线程
        分为三步
        1、将构造函数私有化。
        2、在类中创建一个静态私有本类对象。
        3、提供一个静态方法可以获取到该对象。
    设计单例模式时,该对事物怎么描述,还怎么描述,当需要保证该事物的对象在内存中唯一时,就将以上三步加上即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值