黑马程序员——面向对象

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一、面向对象思想概述

    面向过程:以函数为基础,强调的是过程,关注的是功能行为.

    面向对象:以对象为基础,强调的是对象,关注的是具备某些功能的对象.

    关系:   面向对象是基于面向过程的. 

1、面向对象的思想特点:

    A:更符合人们的思考习惯.

    B: 将复杂的事情简单化.

    C: 将程序员从执行者变成指挥者.

    一个合格的程序与是不会写出诸如"摧毁地球"这样的功能的,他们会写一个方法叫摧毁行星,而把地球作为参数传递进去. 

2、符合面向对象思想的分析方式

    A:分析系统中有哪些对象 --名词提取法

    B: 明确这些对象具备什么功能

    C: 明确对象之间的关系. 

3、类与对象

    :java语言中最基本的单位就是类.是属性和行为的集合.一个抽象的概念.

    对象: 是类的具体的存在.

    类是对象的蓝图和模板。

    java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义。比方说人,整个概念

    对象就是事物的具体实实在在的个体,比方说魏忠贤.   

4、类的组成

    成员变量: 定义在类里面, 方法外面的变量.

    成员方法: 我们之前定义的函数干掉一个static就是成员函数(成员方法)   

    举例: 学生类    

class Student
    {
        Stringname = "张三"; // 最初它初始化的时候是null,然后被"张三"替代. 并不是一初始化就是"张三".
        int age;
        char sex;
       
        publicvoid study()
        {
            System.out.println("学生学习");
        }
       
        publicvoid sleep()
        {
            System.out.println("学生睡觉");
        }
       
        publicvoid eat()
        {
            System.out.println("学生吃饭");
        }
    }
   

    使用学生类:

        1) 如果多个类写在同一个源文件中.文件名必须和带main方法的那个class一样.

        2) 创建对象

            类名 变量名 = new类名();

        3)

            使用成员变量:对象名.成员变量名

            使用成员方法:对象名.成员方法名()           

            注意事项:

                new出来的实例都是在堆内存,

                堆里面的变量都有默认的初始化值.       

    5、什么时候定义成员变量:

        描述事物的属性,就应该定义为成员变量.

        事物的属性是事物的一部分,这个属性对应的变量才能被定义为成员变量。

        java中,成员变量其实就是这个类的属性。

        其他情况,都应该将变量定义成局部变量。

        当然,你如果不按照这个标准做也没有太大问题,只是不符合面向对象的思想特点。 

6、成员变量和局部变量区别

    A: 定义位置区别:

        成员 :类中,方法外面

        局部 :方法中或者方法声明上的形参

    B: 初始化值的区别:

        成员变量:有默认初始化值.

        局部变量:没有默认初始化值,想使用,必须先定义,再赋值,再使用.       

        所有的变量使用前都必须进行初始化.

    C: 存储位置的区别:

        成员 :存储在堆里面.随着对象的创建而存在,随着对象的消失而消失.

        局部 :存储在栈内存.随着方法的调用而存在,随着方法的调用完毕而消失.       

       在使用变量的过程中, 查找变量的顺序是:

        局部 --成员 --父类 -- 报错

        使用过程中,遵循一个原则:就近原则。   

7、匿名对象

    匿名对象的定义:没有名字的对象.匿名对象在一个对象被创建之后,调用对象的方法时可以不定义对象的引用变量,而直接调用这个对象的方法

    应用场景:

        A: 当对象的方法仅进行一次调用的时候.

        B: 匿名对象可以作为实际参数传递.     

  // void
    // String s
    public voidprint(String s)
    {
        sop(s);
    }
    String s ="abc";
    print(s);  
    // 接收一个学生类型数据的方法
    public voidprint(Student s)
    {
        s.study();
    }
   
    Student s =new Student();
    print(s); // 调用方法
    print(newStudent());

二、面向对象的三大特征封装、继承、多态

   封装

   1、封装的定义:隐藏对象的属性和具体的实现细节,仅对外提供公共的访问方式.  

   2、访问权限修饰符: private

         修饰成员变量和成员方法(还可以修饰内部类)

         被修饰的成员特点:不能被其他类直接访问.向外界提供公共的方法进行访问.

   3、学生类:  

  

   class Student
     {
         privateString name;
         private intage;
         privateString userName;
         ...
        
         publicStudent(){}
        
         publicString getName()
         {
             //this  -- s
             returns.name;
         }
        
         public voidsetName(String name)
         {
             //this  -- s
             this.name= name;
         }
        
     } 

     注意: getters setters 不一定要成对出现。

         如果仅允许别人对属性进行赋值,就只提供setter方法,

         同理,如果仅允许别人对属性进行获取,就只提供getter方法.

         但一般都是成对出现.

   4、类的组成

     成员变量:

     构造方法(构造器):

         1) 方法名与类名一致.

         2) 没有返回值类型

         构造方法的作用:

             初始化对象(还可以为成员赋值)       

     成员方法:

         权限修饰符 public  private

     注意:

         如果没有显示的给出任何构造方法,系统将提供一个默认的无参构造.

         一旦显示的给出了构造方法,系统将不再提供默认无参构造.

   建议:总是自己给出无参构造。        

   5. this

     代表方法所属对象的引用. (当前运行类的对象的引用)

     谁调用的方法,this就代表谁.

     应用:

         解决局部变量隐藏成员变量的问题.

         用于构造方法中.    

   

class Student {  
     private Stringname; // 姓名   
     private int age;// 年龄
     // 无参构造
     public Student(){
     }
     // 带参构造
     publicStudent(String name, int age) {
         this.name =name;
         this.age =age;
     }
   
     public StringgetName() {
         return name;
     }
     public voidsetName(String name) {
         this.name =name;
     }
     public intgetAge() {
         return age;
     }
     public voidsetAge(int age) {
         this.age =age;
     }
   }
   
   class StudentTest
   {
     main(String[]args)
     {
         Student s =new Student();// 先使用无参构造
         s.setName("李四"); // 为属性赋值
         s.setAge(19);
        
         Student s1 =new Student("张三", 20);
         // s1 的属性name, age 就初始化好了
     }
   }
   

   6、代码块

     代码块的定义:就是一对{}括起来的代码.

     局部代码块:

   定义位置:方法中的一对{}

         作用:控制变量的生命周期.

     构造代码块:

         定义位置:类中方法外的一对{}

         作用:将构造方法中的共性内容提取出来,减少代码的重复率.

         执行特点:每次创建对象都执行,而且是优先于构造方法.

     静态代码块:

   被static修饰的代码块。

   执行特点:随着类的加载而执行,执行一次。并优先于主函数。用于给类进行初始化。    

   7、 对象初始化过程

     成员变量默认初始化 --显示值替代默认值 -- 构造代码块 -- 构造方法执行

        定义一个新对象都做了哪些事情?

           1、把类名.class文件加载到内存中。

           2、执行该类中的static代码块,如果有得话,给该类进行初始化。

           3、在堆内存中开辟空间,分配内存地址。给对象

           4、在堆内存中建立对象的特有属性。并进行默认初始化。

           5、对属性进行显示初始化。

           6、对对象进行构造代码块初始化。

           7、对对象进行对应构造函数初始化。

           8、将内存地址赋给栈内存中的对象名变量。   

   8static 关键字

     修饰成员变量和成员方法.(还可以修饰内部类)

     特点:

         A:随着类的加载而加载,优先对象于对象而存在.

         B: 被类的所有对象共享.

         C: 可以使用类名直接调用.       

     类变量: static修饰的成员变量.

     实例变量:  没有static修饰的成员变量

     注意事项:

         A:静态方法中没有this关键.

         B: 静态方法只能访问静态成员变量和静态成员方法.

         C: 静态成员强烈建议使用类名调用.

   9.Math类的功能

   Math -- 数学类(提供了常用的算术运算)

     Math 类的所有方法都是静态的,所以类名.方法名()直接调用.

         int abs(inti)——获取绝对值

         doubleceil(double d)——向上取整

         doublefloor(double d)——向下取整

         longround(double d)——四舍五入

         intround(float f)——四舍五入

         doublerandom()——返回[0.0, 1.0)之间的一个随机小数

             补充:左闭右开原则在java中的方法设计上有通用性.

         int max(inti, int j)——获取最大值

   继承

   1、继承的概念:

     把多个类中相同的内容抽取出来,单独定义到一个类(父类),再定义其他类(子类)的时候,继承父类即可.

         子类就可以使用父类所有的非私有的属性和行为.    

   继承的格式:

         class 子类名 extends父类名{}

     继承的好处:

         A: 提高代码复用性,降低代码的重复率.

         B: 让类与类之间产生关系,是多态的前提.

     继承的特点:

         java的继承只支持单继承,为了避免调用的不明确性.

         但是java支持多层()继承.     

   2、什么时候定义继承:

         体现的是 is a的关系.

         尽量不要为了使用部分功能而采用继承关系.

   3.、子父类间成员变量的使用:

     同名的成员变量:

         局部 --成员 -- 父类 -- 报错

     局部位置输出局部:

         直接使用变量名即可

     局部位置输出成员:

         this.变量名

     局部位置输出父类:

         super.变量名

   例:       

   class Fu
     {
         int num =10;
   
         public voidfun()
         {
             //intnum = 30;
             System.out.println(num);   
         }
     }
    
     class Zi extendsFu
     {
         int num2 =20;
        
         public voidshow()
         {
             int num3= 30; 
         }
     }
    
     class ZiTest
     {
         publicstatic void main(String[] args)
         {
             Zi zi =new Zi();
             zi.fun();
         }
     }  
   

   4.this super

     this 代表当前运行类的对象的引用.

     super 代表父类内存空间的标识.(可以理解成父类对象的引用)

     应用:

         1) 成员变量

             this.变量名 --本类成员变量

             super.变量名 --父类成员变量

         2) 构造方法:

             this(参数) --调用本类其他构造

             super(参数) --调用父类构造

             -- 都是通过参数进行匹配

             注意:必须放在构造方法的第一行.

         3) 成员方法

             this.方法名(); --本类的方法

             super.方法名(); --父类的方法        

   5.、成员方法的重写与重载

     重写: 子父类之间,出现方法完全一致(返回值类型,方法名, 参数列表)的情况,称为方法的重写.

     重载与重写的区别:

         重载:一个类中,方法名相同,参数列表不同(参数的个数或者数据类型或者顺序),与返回值类型无关.

         重写:子父类之间,出现方法完全一致(返回值类型,方法名, 参数列表)的情况,称为方法的重写.        

     方法的重写注意问题:

         1) 父类的私有方法不能被重写.

         2) 子类重写父类的方法,不能缩小父类方法的访问权限.

         3) 静态方法只能被静态方法重写.

     应用:

         子类的方法既想继承父类方法的功能,又有自己特有的功能,就可以使用super.方法名()来调用父类的功能,并且添加自己的功能.        

   6.、继承中的构造方法执行顺序

     子类中的构造方法默认都去访问了父类中的无参构造,因为构造方法的第一行都有一句默认的super();

     目的是为了初始化父类的成员.

     如果父类没有无参构造,怎么办?

         1) super(参数)去调用父类的带参构造.

         2) this(参数)去调用本类的其他构造,想调用的这个构造必须最终调用了父类的带参构造.

     构造方法没有重写.

         因为构造方法不被子类继承.只不过子类创建对象的时候调用了父类的构造方法,去初始化了父类的成员.

     但构造方法可以存在重载关系.

   7. 子父类间代码块执行顺序

     父静态代码块 --子的静态代码块 -- 父的构造代码块 -- 父的构造方法 -- 子的构造代码块 -- 子的构造方法    

     特点:

         静态代码块,随着类的加载而加载,但是只执行一次.

         构造代码块,在构造方法的执行前会执行,并且每次创建对象都执行.    

   8. 任何类都直接或者间接继承自Object

   9. 子类访问父类私有成员的方法

     1) 通过父类提供的公共的getset方法.

     2) 子类通过调用父类的带参构造.

     基础思想都是一致的:

         对于私有的成员,除了在能所属类中使用之外,不能在其他任何地方直接使用。

         但是可以在所属类中定义公共的访问方式,然后外界通过这种公共的访问方式供其他类或者对象使用。       

   10. final关键字

     最终的意思.

         修饰的成员变量 --其实是一个常量, 一旦被赋值,将不再发生改变.

             注意: final修饰引用数据类型,指的是修饰的引用的指向不再发生改变.

         修饰的成员方法 --不能被子类重写.

         修饰的类 --不能被继承.

   多态

   1、多态的概念:对象在不同时刻表现出来的不同状态. --父类子对象

     多态的前提:

         A: 要有继承或者实现关系.

         B: 要有方法的重写.

         C: 要有父类引用指向子类对象.   

     多态的成员特点:

   多态中成员函数的特点

   如果父类中有一个非抽象的方法,而子类继承后又将其复写了,在多态运行时,父类的引用调用这个同名函数时,被运行的将是父类中的方法。

           简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

   多态中成员变量的特点

   多态中的父类引用调用成员变量时,如果父类和子类有同名的成员变量,那么被调用的是父类中的成员变量。

   简单总结就是:编译和运行都看左边。

         方法有重写,而变量没有          

   2、 多态的弊端及解决方案

     弊端: 父类引用不能使用子类特有的功能.

     解决: 强制类型转换.

         Fu fu = newZi();  -- 向上转型

         Zi zi =(Zi)fu; -- 向下转型

   3、类型转换异常

     ClassCastException

         当试图将对象强制转换为不是实例的子类时,抛出该异常。

     如何避免避免:

         向下转型

   转换成对象本来就是的类型或者其父类型.

   4、 多态的好处

     提高代码的扩展性和可维护性.

     开发原则: 对扩展开放,对修改关闭.       

     :

     

    class Animal...
        
         class Dogextends Animal ...
        
         class Catextends Animal ...
        
         class Pigextends Animal ...
        
         // 工具类中的方法
         public voidprintAnimal(Animal a){
             ...
             // 多态中方法调用的特点
         }
        
         // 根据多态特点,父类引用可以指向子类对象
         Dog d = newDog(); // 具体子类引用和子类对象
        
         Animal a2 =new Dog(); // 或者直接这样创建对象也是可以的. 多态用法
        
         // 调用方法
         printAnimal(d);// 相当于Animal a1 = d; // 赋给父类引用是可以的, 向上转型
         printAnimal(a2);// 当然也可以, a2本身就是Animal类型
        
         // 同理: 再创建Cat和Pig对象, 同样都可以传递进printAnimal(Animal a) 方法.
         // 所以,工具类不需再发生改变,而很好的提高了代码的扩展性.
         Cat c = newCat();
         Pig p = newPig();            

   5、抽象类

     抽象方法: 只有方法声明,没有方法体.要用abstract关键字修饰.

     抽象类: 具有抽象方法的类就可以被称为抽象类.

     抽象类的基本特点:

         1) 抽象类和抽象方法必须用abstract关键字修饰.

         2) 有抽象方法的类一定是抽象类,但是抽象类中可以没有抽象方法.

         3) 抽象类不能被实例化,通过子类对象进行实例化.

         4) 子类继承自抽象类,要么子类继续抽象,要么重写父类中所有的抽象方法.

             -- 强制要求子类做某些事情.

     抽象类的成员特点:

         成员变量:  可以是变量, 可以是常量.

         构造方法:  有构造方法用来对父类数据进行初始化.

         成员方法:

             可以有抽象方法 --要求子类做某些事情

             可以有非抽象方法 --供子类继承.        

     抽象类案例:

         黑马程序员有两类老师:

             基础班老师

                 属性:姓名,年龄

                 行为:讲课(JavaSE)

             就业班老师

                 属性:姓名,年龄

                 行为:讲课(JavaEE)

   

         由于讲课内容不一样,但是都有讲课的功能。

         所以,我们把讲课抽取出来。定义一个Teacher类,强制要求其子类必须会讲课。

         接着来再定义一个基础班老师继承Teacher,一个就业班老师继承Teacher,最后在另外一个类中测试两个不同老师的成员。

     注意:抽象关键字abstract不可以和finalprivatestatic关键字共存

         1) final

             因为被final修饰的类不能被继承,被final修饰的方法不能被重写。

         2) private

             因为被private修饰的方法不能重写,但是abstract方法要求重写。

         3) static

             因为一个方法要是同时被staticabstract修饰,那么这个方法就可以类名.方法名 调用.但是此方法是抽象的,调用也无意义,所以就导致staticabstract不能共存.

   6、 接口

     针对于一个抽象类中所有的方法都是抽象方法这种情况, java提供了一个新的技术,叫做接口.

         定义类

             class A

         定义接口:

             interfaceB

             {

                 // 全部都是抽象方法

             }

         注意:接口并不是一个类. 它其实更像一个规则的体现. 可以理解成一个特殊的抽象类.    

         类继承自类的格式:

             class Aextends B        

         类实现接口的格式:

             class Aimplements B

     接口的基本特点:    

         1) 接口不能被实例化.

         2) 实现类实现接口,要么实现类定义为抽象的,要么重写接口中的所有抽象方法.

     接口的成员特点:

         1) 成员变量:

             全部都是常量.默认修饰符: public static final

         2) 构造方法:没有

         3) 成员方法:

             全部都是抽象方法.默认修饰符: public abstract

             推荐手动给出修饰符.

   7、 类与接口的关系

     类与类:

         继承关系,只能单继承,但是可以多层继承.

     类与接口:

         实现关系.可以单实现,可以多实现.

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

     接口与接口:

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

   8. 接口的思想特点

     1) 对外暴露的规则.

     2) 是程序的功能扩展.

     3) 降低耦合性.

     4) 多实现.

   9、抽象类与接口的区别

     1) 成员特点:

         抽象类:

             成员变量:

                 可以是变量,可以是常量.

             构造方法:

                 有构造方法用来对父类数据进行初始化.

             成员方法:

                 可以有抽象方法 --要求子类做某些事情

                 可以有非抽象方法 --供子类继承.

         接口:

             成员变量:

             全部都是常量.默认修饰符: public static final

             成员方法:

             全部都是抽象方法.默认修饰符: public abstract

     2) 关系特点:

         类与类:

             继承关系,只能单继承,但是可以多层继承.

         类与接口:

             实现关系.可以单实现,可以多实现.

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

         接口与接口:

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

     3) 设计理念的区别:

         抽象类定义的是系统的共性内容,体现的是 is a的关系.

         接口定义的是系统的扩展功能,体现的是 like a 的关系.

你可能感兴趣的:(黑马程序员——面向对象)