黑马程序员_面向对象笔记

来源:互联网 发布:邯郸学院网络教学平台 编辑:程序博客网 时间:2024/06/11 13:12

面向对象

    面向对象是相对面向过程而言,面向对象和面向过程都是一种思想,面向过程强调的是功能行为,而面向对象是以对象为基础强调的是对象.

   特点:

        (1)复杂的事情简单化

        (2)由执行者转变为指挥者.

        (3)符合现在人们思考的一种思想

完成需求时:
    1. 先要去找具有所需的功能的对象来用。
    2. 如果该对象不存在,那么创建一个具有所需功能的对象。
    这样可以简化书写开发并提高代码的复用性。

  面向对象示例:

我的电脑坏了,我不需要自己去学习怎么修电脑,不需要知道电脑哪里出问题,不需要买零件,只需要找个会修电脑的帮我修就可以了。由执行者变成指挥者了。

示例:

把鱼放进冰箱

1.打开冰箱

2.存储鱼

3.关闭冰箱

上述都是功能和行为,这就是面向过程的思想体现

而面向对象则是:将功能封装进对象,强调具备了功能的对象

1.冰箱打开

2.冰箱储存

3.冰箱关闭

上面可以看到都是以冰箱为主体,我们只是在调用冰箱具备的功能

在程序中,过程其实就是函数;对象是将函数等一些内容进行了封装。

 

   面向对象的三大特征:
    封装(encapsulation)
    继承(inheritance)
    多态(polymorphism)

1:类与对象的关系

使用计算机语言来描述现实生活中的事物

类是对具体事物的抽象,对象则是实实在在的个体

1.类的定义

描述事物的属性和行为

属性:对应类中的成员变量。
行为:对应类中的成员函数。

定义类其实在定义类中的成员(成员变量和成员函数)

比如定义一个Person类:

首先分析人的属性和行为

属性:姓名,年龄,性别,身高,体重
行为:吃饭,睡觉

转变成java类:

成员变量:

姓名:name,年龄:age,性别:sex,身高:height,体重:weight

成员函数:

吃饭:eat();睡觉:sleep();

然后通过创建对象来调用学生的内容。

Person p = new Person();

2:成员变量和局部变量的区别:
    1. 成员变量直接定义在类中,在整个类中都可以被访问,

局部变量只定义在方法,参数,语句中,只在所属的区域有效。

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

局部变量存在于栈内存中,随着所属区域的运行而存在,结束而释放。


    3. 成员变量有默认初始化值,局部变量没有默认初始化值。


   3匿名对象:
       没有名字的对象。
      使用场景:
               1当对象方法仅调用一次的时候。
               2匿名对象可以作为实际参数进行传递。

示例:

class PersonDemo {public static void main(String[] args) {new Person().show();cons(new Person());}public static void cons(Person p){p.name = "李四";p.age = 18;System.out.println(p.name+":::"+p.age);}}class Person{String name = "张三";int age = 20;public void show(){System.out.println(name+":::"+age);}}

注:当对象对成员进行多次调用时,不能使用匿名对象。必须给对象起名字。

4:封装

 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

    好处:
    1. 将变化隔离。
    2. 便于使用。
    3. 提高重用性。
    4. 提高安全性。

    封装原则:
    1. 将不需要对外提供的内容都隐藏起来。
    2. 把属性都隐藏,提供公共方法对其访问。

示例:

package com.itheima;public class Person {private int age ;private String name;public Person(){}public Person(String name,int age){this.name=name;this.age=age;System.out.println(name+":::"+age);}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

注:私有仅仅是封装的一种体现形式而已。
5:构造函数:

  特点:

1、函数名必须与类名相同。
    2、不需要定义返回值类型。
    3、没有具体的返回值。

作用:给对象初始化

注:所有对象都必须初始化才可以使用,在构造函数前加返回值就是一般函数,我们如果没写构造方法系统会默认给出一个无参构造方法,如果我们写了构造方法系统则不会给无参构造方法,建议手动给出无参构造,构造函数可以重载,传递参数不同即可。

一般函数和构造函数什么区别呢?

构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化,初始化动作只执行一次。
    一般函数:对象创建后,需要函数功能时才调用。

而且两个函数的定义格式不同

构造代码块和构造函数的区别:

构造代码块:是给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块。只要对象一建立。就会调用这个代码块。

构造函数:是给与之对应的对象进行初始化。它具有针对性。

this关键字

代表所在函数所属对象的引用即代表本类的引用

示例:

package com.itheima;public class Person {private int age ;private String name;public Person(){}public Person(String name,int age){this.name=name;this.age=age;System.out.println(name+":::"+age);}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

static关键字

用于修饰成员(成员变量和成员函数)。
    被修饰后的成员具备以下特点:
    1、随着类的加载而加载。
    2、优先于对象存在。
    3、被所有对象所共享。
    4、可以直接被类名调用。

  成员变量和静态变量的区别?
    1. 两个变量的生命周期不同
        成员变量随着对象的创建而存在,随着对象被回收而释放,

成员变量也称为实例变量。
        静态变量随着类的加载而存在,随着类的消失而消失,

静态变量也称为类变量。
    2. 调用方式不同
        成员变量只能被对象调用。
        静态变量可以被对象调用,还可以被类名调用。
    3. 数据存储位置不同
       成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
       静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。

    使用注意:
    1. 静态方法只能访问静态成员,如果访问非静态成员,就会报错!

   原因:静态方法和变量存在的时候,对象还不存在,非静态变量也不存在,肯定无法访问。

2.静态方法中不可以写this,super关键字。

原因:静态方法存在的时候,对象还不存在,this代表的就是调用方法的那个对象,既然不存在,肯定不可以写在静态方法中。
所以静态函数上的同步锁是该类对象的字节码文件

静态代码块、构造代码块、构造函数同时存在时的执行顺序:静态代码块 > 构造代码块 > 构造函数;

 

6:继承

父类的由来:其实是由多个类不断向上抽取共性内容而来的。

格式:
class A extends B 
{

}

类A:子类,派生类
类B:父类,基类,,
注:子类可以直接访问父类中的所有非私有成员。

若类不想被继承,可以使用final,成为最终类,

final它修饰的类,不能被继承,但是可以继承其他类。

它可以修饰类,成员变量,成员方法。

final成员变量是常量

final修饰的成员方法,不能被子类重写。

继承的好处:

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

2:让类与类之间产生了关系,提供了另一个特征多态的前提。

Java只支持单继承不支持多继承,但支持多实现

 This:代表是本类类型的对象引用。

Super:代表是子类所属的父类中的内存空间引用。

 注意:子父类中通常是不会出现同名成员变量的,因为父类中只要定义了,子类就不用在定义了,直接继承过来用就可以了

当子父类中出现了一模一样的方法时,建立子类对象会运行子类中的方法。好像父类中的方法被覆盖掉一样。所以这种情况,是函数的另一个特性:覆盖(复写,重写)

注意:子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super(); 

如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数。

如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数。

Super和this只能有一个定义在第一行,只能出现其中一个。

Super和this必须放在第一行的原因:

因为super()或者this()都是调用构造函数,构造函数用于初始化,所以初始化的动作要先完成。

子父类代码块的执行顺序:

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

 

7.抽象类abstract

抽象类的特点:

1:抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。

2:抽象方法只定义方法声明,并不定义方法实现。

3:抽象类不可以被创建对象(实例化)。

4:只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。

 

注:抽象类中既可以定义抽象方法,又可以定义非抽象方法

抽象类不可以和final,private,static共存

抽象类中的构造函数是为了给子类对象进行初始化

 

8.接口

格式:

Interface 接口名{}

接口中包含的成员,全局常量、抽象方法。

示例:

Interface inter

{

public static final int x = 3;

public abstract void show();

}  

类与类之间存在着继承关系,类与接口中间存在的是实现关系。

接口与接口可以单继承,也可以多继承

继承用extends  ;实现用implements ;

接口可以多实现

接口中的成员修饰符是固定的。全都是public的。

特点:

1:接口是对外提供的规则。

2:接口是功能的扩展。

3:接口的出现降低了耦合性。

抽象类和接口的区别:

1:抽象类只能被继承,而且只能单继承。

接口需要被实现,而且可以多实现。 

2:抽象类中可以定义非抽象方法,子类可以直接继承使用。

接口中都有抽象方法,需要子类去实现。

3:抽象类使用的是  is a 关系。

接口使用的 like a 关系。 

4:抽象类的成员修饰符可以自定义。

接口中的成员修饰符是固定的。全都是public的。

9.多态:

对象在不同时刻表现出的不同状态

(猫,猫科,动物)

父类引用或者接口的引用指向了自己的子类对象:Animal a = new Cat();

多态的前提:

1.必须要有关系,如继承,实现

2.必须有覆盖操作

3.父引用指向子类对象

  多态中子父类成员变量的特点:

1.成员变量:编译运行都看左边

2.成员函数:编译看左边,运行看右边

3.静态函数:编译运行都看左边

示例:

class Person{void eat(){System.out.println("吃饭");}void sleep(){System.out.println("睡觉");}}class Student extends Person{void sleep(){System.out.println("熬夜学习");}void study(){System.out.println("学习");}}class {public static void main(String[] args) {Person p = new Student(); //Person对象被提升为了学生类型。 p.sleep();//p.study();  //错误.Student s = (Student)p; //将人类型强制转换成学生类型。 p.study();//在多态中,自始自终都是子类对象在做着类型的变化。}}

10.匿名内部类:

没有名字的内部类

匿名内部类的格式:new 父类名&接口名(){ 定义子类成员或者覆盖父类方法 }.方法。

示例:

package com.itheima;public class Test715 {public static void main(String[] args){new Thread()//新建一个匿名内部类{public void run()//覆盖run方法{for(int i=0;i<=100;i++){System.out.println(i);}}}.start();//开启线程new Thread(){public void run(){for(int i=0;i<=100;i++){System.out.println(i);}}}.start();new Thread(){public void run(){for(int i=0;i<=100;i++){System.out.println(i);}}}.start();}}





0 0
原创粉丝点击