黑马程序员-------------java基础----------------面向对象

来源:互联网 发布:flash for mac破解版 编辑:程序博客网 时间:2024/06/05 11:30


------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

第一讲   面向对象的概述

1、三大特征与概述
 封装、继承、多态
理解:面向对象就是相对面向过程而言的。
比如:c语言强调的是功能行为:打开冰箱——>把食品装进冰箱——>关闭冰箱,强调的是行为。
而Java面向对象的思想就是强调具有功能的对象:冰箱打开,冰箱存储,冰箱关闭。
表面上你自己亲自在做,实际上是冰箱在做这些动作。
好处:可以将复杂的事情简单化,将程序员从执行者转换成了指挥者。
举例:当我们去餐厅吃饭时,我们只用给服务人员说我们要吃什么,不用亲自去做,这时,厨师就是对象,
他具备做饭的功能,我们将他看作对象,就从执行者转换成了指挥者。
注意:
在Java的开发过程,其实就是不断的创建对象,使用对象,指挥对象做事情。设计的过程,其实就是在管理和维护对象之间的关系。

第二讲 类与对象

1、类就是对事物的描述。
  生活当中描述事物无非就是描述事物的属性和行为。如:人的身高,体重等属性;讲话跑步等行为。
  Java则是用类class来描述对象的属性和行为。定义类其实就是在定义类中的成员(成员变量和成员函数)。
   属性:对应类中的成员变量。
    行为:对应类中的成员函数。
class Car
{
 int num;
 public void run()
 {
  System.out.println("car run");
 
 }
}
这就是创建了一个汽车类
num就是一个成员变量
run() 就是一个成员函数
2、对象
对象即是该类事物实实在在存在的个体。
创建格式:
Car c=new Car();
c 就是一个类类型变量,就是一个对象
在java中指挥方式是:对象.对象成员
例如:c.num=4;对成员变量赋值
c.run()调用方法
3、成员变量和局部变量
成员变量:

       成员变量定义在类中,在整个类中都可以被访问。

        成员变量随着对象的建立而建立,存在于对象所在的堆内存中。

          成员变量有默认初始化值。
局部变量:

         局部变量只定义在局部范围内,如:函数内,语句内等。

       局部变量存在于栈内存中。

         作用的范围结束,变量空间会自动释放。

         局部变量没有默认初始化值
4、匿名对象
        匿名对象是对象的简化形式。
       匿名对象两种使用情况
           1、当对对象方法仅进行一次调用的时。
     比如:new Car().num=3;如果类中还有其他成员变量,color,这时还要对color赋值,不能用匿名对象了。只能给对象起名字。
          2、匿名对象可以作为实际参数进行传递。
   
第三讲  构造函数
1、 特点:
       函数名与类名相同。
      不用定义返回值类型。
 不可以写return语句。
 比如Car(){}就是一个空参数的构造函数。

2、 作用:

        给对象进行初始化。
  比如:Car c=new Car();

3、构造函数的小细节:

        当一个类中没有定义构造函数时,那么系统就会默认给该类加入一个空参数的构造函数。当在类中自定义了构造函数后,默认的构造函数就没有了。

4、构造函数和一般函数在写法上有不同。
 在运行上也有不同:
        构造函数式在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,给是对象添加对象具备的功能。一个对象建立,
  构造函数只运行一次。而一般方法可以被该对象调用多次。
5、构造代码块

  作用:给对象进行初始化。对象一建立就运行,而且优先于构造函数运行。

和构造函数的区别:

       构造代码块是给所以对象进行初始化。
       而构造函数是给对应的对象初始化。

构造代码块中定义的是不同对象共性的初始化内容。
6、子父类中的构造函数
在对子类对象进行初始化时,弗雷德构造函数也会运行,是因为子类的所有构造函数第一行默认的都是super(),
super与this用法几乎一样。
注意:为什么子类一定要访问父类的构造函数?
因为父类的数据子类可以直接获取,所以子类在创建对象时,需要先查看父类时如何对这些数据初始化的。
重点:
如果要访问父类的指定的构造函数,可以用super语句。当父类中没有空参数的构造函数时,一定要手动指出要访问的具体构造函数,
不然编译失败。总之,子类中至少会访问父类中的一个构造函数。
class Person
{
 private String name;
 private int age;
 Person()
 {
  System.out.println(name+":::"+age);
 }
 Person(String n)
 {
  name=n;
  System.out.println(name+":::"+age);
 }
 Person(String n,int a)
 {
  name=n;
  age=a;
  System.out.println(name+":::"+age);
 }

}
class  PersonDemo
{
 public static void main(String[] args)
 {
  Person p1=new Person();对应的是空参数的构造函数,初始化值为0
  Person p2=new Person("zhangsan");对应的是有姓名构造函数,初始化值为zhangsan
  Person p3=new Person("zhangsan",20);对应的是有姓名,年龄构造函数,初始化值为zhangsan ,20
 
 }
}

第四讲 this关键字

1、this.代表本类对象。
 简单说:哪个对象在调用this所在的函数,this就代表哪个对象。
this的应用:
       当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
       但凡本类功能内部使用到了本类对象,都用this表示。
this语句
       用于构造函数之间进行互相调用
        thi语句只能定义在构造函数的第一行。因为初始化要先执行
有了this关键字,对上面代码进行优化
class Person 

    private String name; 
    Person(int age)//局部变量时age,成员变量也是age 
 { 
        this.age = age;//this能够很好区分 
    } 
    Person(String name) 
   { 
       this.name = name;//这里用this表示调用构造方法的对象 
   } 
   Person(String name,int age) 
    { 
        this.name = name; 
        this.age = age; 
    } 
   public void speak() 
   { 
        System.out.println("name="+name+"...age="+age); 
     
  } 
   

第五讲  静态static

1、static是一个修饰符,用于修饰成员(成员变量和成员函数)。当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,
还可以直接被类名调用。格式:类名.静态成员。
static特点:

        随着类的加载而加载。 也就是说:静态会随着类的消失而消失,说明它的生命周期最长。

        优先于对象存在。明确一点:静态是先存在。对象是后存在。

        被所有对象所共享。

      可以直接被类名所调用。

      由于静态成员可以直接被类名调用,因此静态成员变量又称为类变量。而非静态成员变量又被称为实例变量。

2、实例变量和类变量的区别:

        1、存放位置。

              类变量随着类的加载而存在于方法区中。

              实例变量随着对象的建立而存在于堆内存中。

        2、生命周期。

              类变量生命周期最长,随着类的消失而消失。

             实例变量生命周期随着对象的消失而消失。

3、静态有利有弊:

        利处:对对象共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。

        弊端:生命周期过长。

                   访问出现局限性。(静态虽好,只能访问静态)。

4、静态需要清楚的几个小问题:

什么时候使用静态?

        从两方面下手: 因为静态修饰的内容有成员变量和函数。

1、什么时候定义静态变量(类变量)呢?

        当对象中出现共享数据时,该数据被静态所修饰。

        对象中的特有数据要定义成非静态存在于堆内存中。

2、什么时候定义静态函数呢?

        当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。

5、静态使用注意事项:

        1、静态方法只能访问静态成员。

              非静态方法既可以访问静态也可以访问非静态。

        2、静态方法中不可以定义this,super关键字。

              因为静态优先于对象存在。所以静态方法中不可以出现this。

        3、主函数是静态的。

6、静态代码块:

        格式:

              static

              {

                           静态代码块中的语句。

              }

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

重点:静态多用于工具类中,将工具类生成说明书。
/**
这是一个可以对数组进行相关操作的工具类,该类提供了取数组的最值、排序等功能。
@author Godream
@version V1.0

*/ 
//类名权限要最大才能创建说明书文档 
public class ArrayTool  

     private ArrayTool() //私有化构造函数是为了让其不能创建对象。 
   { 
     
   } 
 
   /**
   这个功能用于得到int类型数组中的最大值
    @param arr 接收一个int类型的数组
   @return 返回接收的该数组的最大值
   */ 
    public static int getMax(int[] arr) 
    { 
       int max=0; 
       for (int x=1;x<arr.length ;x++ ) 
       { 
            if(arr[x]>arr[max]) 
               max=x; 
       } 
        return arr[max]; 
    } 
     
    /**
    这个功能用于得到int类型数组中的最小值
    @param arr 接收一个int类型的数组
    @return 返回该数组的最小值
   */ 
    public static int getMin(int[] arr) 
    { 
        int min=0; 
        for (int x=1;x<arr.length ;x++ ) 
        { 
            if(arr[x]<arr[min]) 
               min=x; 
        } 
        return arr[min]; 
    } 
 
    /**
    对int类型数组进行选择升序排列
    @param arr 接收一个int类型的数组
    */ 
    public static void selectSort(int[] arr) 
    { 
        for (int x=0;x<arr.length-1 ; x++) 
       { 
           for (int y=x+1; y<arr.length; y++) 
            { 
               if(arr[x]>arr[y]) 
                    swap(arr,x,y); 
            }
    }
       
    } 
 
    /**
    对int类型数组进行冒泡升序排列
   @param arr 接收一个int 类型数组
   */ 
    public static void bubbleSort(int[] arr) 
   {    
        for (int x=0;x<arr.length-1;x++ ) 
        { 
            for (int y=0;y<arr.length-x-1;y++ ) 
           {    
                if(arr[y]>arr[y+1]) 
                    swap(arr,y,y+1); 
           } 
        } 
    } 
 
   /**
    对数组中的两个元素进行位置交换
   @param arr 接收一个int类型的数组
    @param a 要置换的元素角标
    @param b 要置换的元素角标
   */ 
    private static void swap(int[] arr,int a,int b) 
    { 
      arr[a]=arr[b]+(arr[b]=arr[a])*0; 
    } 
 
   /**
    遍历数组:打印数组中所有元素,形式为:[elemet1,elemet2,...]
    @param arr 接收一个int类型的数组
    */ 
   public static void printArray(int[] arr) 
    { 
        System.out.print("["); 
       for (int x=0; x<arr.length-1; x++) 
        { 
           System.out.print(arr[x]+","); 
        } 
       System.out.println(arr[arr.length-1]+"]"); 
   } 
 } 

第六讲  单例设计模式

1、解决的问题:保证一个类在内存中的对象唯一性。
比如:多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中数据,
又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。
2、单例步骤
 1,因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法再创建该类对象;
 2,就在类中创建一个本类的对象;
 3,定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。
3、单例的两种方式
//饿汉式
class Single{
private Single(){}  //私有化构造函数。
private static Single s=new Single(); //创建私有并静态的本类对象。
public  static  Single  getInstance(){ //定义公有并静态的方法,返回该对象。
return  s;
}
}

//懒汉式:延迟加载方式。
Class  Single2{
private  Single2(){}
private  static  Single2  s=?null;
public  static  Single2  getInstance(){
if(s==null)
s  = new  Single2();
return  s;
}
}

第七讲  继承
1、继承是类与类之间的所属关系
当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可。
这时,多个类可以称为子类,单独的这个类称为父类。
比如:学生有姓名和年龄,工人有姓名和年龄,向上抽取去人也是有姓名和年龄的。这时候就可以将学生和工人去继承人。
重点:千万不要为了获取其他类中的功能,简化代码而继承。必须是类与类之间有所属关系才可以继承。这种所属关系的表示为is a。
2、优点
  提高了代码的复用性。
      让类与类之间产生了关系。有了这个关系,提供了多态的前提。
注意:Java语言中,只支持单继承,不支持多继承。例:一个儿子只能有一个父亲。
   原因:因为类与类多继承的话,容易带来安全隐患。如:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪个一个。
   但是Java保留了这种机制,并用另一种体现形式来完成。叫多实现。
 
//定义一个人父类 
class Person 

   //名字和年龄是人的共有属性 
   String name; 
    int age; 
     
    //在构造函数中对名字和年龄进行初始化 
    Person(String name,int age) 
    { 
       this.name=name; 
       this.age=age; 
      System.out.println(name+"  "+age); 
    } 
    //人都具有睡觉的功能 
   void sleep() 
    { 
        System.out.println("sleep"); 
    } 

//定义一个学生,继承人,作为子类 
class Student extends Person 

    Student(String name,int age) 
    { 
        super(name,age);    //super关键字表示父类,因为姓名和年龄在父类中进行了初始化动作,在这里可以直接调用 
    } 
    //学生具有特有的功能,学习 
    void study() 
    { 
       System.out.println("study"); 
   } 
 

 
class Demo 

    public static void main(String[] args) 
    { 
        Student s=new Student("zhangsan",20); 
        System.out.println(s.name="wangwu"); 
        s.sleep(); 
        s.study(); 
    } 

3、子父类出现后,类成员的特点:

1、变量

       如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this。子类要访问父类中的同名变量,用super。

        super的使用和this的使用几乎一致,且两者都存在于方法区中。

          this表示本来对象的引用。   

          super表示父类对象的引用。

2、函数——覆盖

       当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。
    这种情况是函数的另一个特性:重写(覆盖)。
重点:重载与重写的区别
重写方法的规则:
1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
2、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
3、访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常IOException,
在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。
重载的规则:
1、必须具有不同的参数列表;
  如果参数个数不同,就不管它的参数类型了!
      如果参数个数相同,那么参数的类型或者参数的顺序必须不同。
2、可以有不同的返回类型,只要参数列表不同就可以了;
3、可以有不同的访问修饰符;
      可以大于原来的访问权限,也可以小于原来的权限。
4、可以抛出不同的异常;
记住:final关键字
 final作为一个修饰符。具有以下特点:

        1、可以修饰类、函数、变量。

        2、被final修饰的类不可以被继承。这样就可以避免被继承、被子类复写功能。

        3、被final修饰的方法不可以被复写。

        4、被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,又可以修饰局部变量
5、内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。


第八讲  抽象类
1、抽象类
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
        抽象类的由来:
        多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,
  那么只有功能声明,没有功能主体的方法称为抽象方法。
例如:学生都睡觉,但是睡觉的姿势不一样,这时就要将睡觉的方法定义成为抽象的。
2、抽象类的特点
  1、抽象类和抽象方法必须用abstract关键字来修饰。

        2、抽象方法只有方法声明,没有方法体,定义在抽象类中。

        格式:修饰符abstract返回值类型  函数名(参数列表);

        3、 抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:

        抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。

        而且抽象类即使创建了对象,调用抽象方法也没有意义。

        4、抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。

注:抽象类中可以有非抽象的方法。
重点记忆:抽象类与一般类的区别

1、抽象类和一般类没有太大的不同。该如何描述事物,还是如何描述事物。只不过,该事物中出现了一些不知道具体内容的方法部分。这些不确定的部分,也是该事物的功能,需要明确出来,但是无法定义主体。通过抽象方法来表示。

        2、抽象类比一般类多了个抽象函数。就是在类中可以定义抽象方法。

        3、抽象类不可以实例化。

        4、抽象类虽然不能创建对象,但是也有构造函数。供子类实例化调用。

注意:被abstract修饰的函数不能同时被private、final、static修饰。
/*
假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性:
姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个
奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方
法进行属性访问。
 
员工类:name id pay
 
经理类:继承了员工,并有自己特有的bonus。

*/ 
 
//员工类,也是父类 
abstract class Employee 

    private String name;//姓名 
    private String id;  //工号 
    private double pay;  //工资 
    
   //自定义构造函数初始化 
   Employee(String name,String id,double pay) 
    { 
        this.name = name; 
        this.id = id; 
       this.pay = pay; 
    } 
    
    public abstract void work();//抽象的工作方法 
 

 
//经理类,继承员工类 
class Manager extends Employee 

   private int bonus;//特有的奖金属性 
    Manager(String name,String id,double pay,int bonus)//子类的构造方法 
    { 
        super(name,id,pay);//调用超类中的构造器 
        this.bonus = bonus; 
    } 
    public void work()//经理类的工作方法内容 
    { 
        System.out.println("manager work"); 
    } 

 
//普通员工类,继承员工类 
class Pro extends Employee 

    Pro(String name,String id,double pay) 
    { 
       super(name,id,pay); 
    } 
    public void work()//普通员工类的工作方法内容 
    { 
        System.out.println("pro work"); 
    } 

 
class  AbstractDemo  

    public static void main(String[] args)  
    { 
        new Manager("manager","001",10000,2000).work(); 
        new Pro("pro","020",5000).work(); 
    } 

         ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

0 0
原创粉丝点击