Java基础-05-面向对象

Java基础-面向对象

面向对象入门

1、面向对象概述

(1)、理解面向对象:一种思考思想。如图:

Java基础-05-面向对象_第1张图片

(2)、面向对象的优点:

复杂的事情变简单。(以前:执行 。现在:指挥)

2、面向对象(举例)

JAVA----->一切皆对象

3、面向对象(类与对象的关系)

(1)、例如:人开门(名词提炼法)

人{        开门(门){门.开();}         }
门
{
        开(){操作门轴等}
}

(2)、

  • 面向对象有3个特征:封装、继承、多态。
  • 以后开发:其实就是找对象使用,没有对象,就创建一个对象,即找对象,建立对象,使用对象,维护对象的关系。
  • 类和对象的关系:

      类:就是对现实生活中的事物的描述。
      对象:就是这类事物,实实在在存在的个体。例如:张三、李四。(现实生活中的对象)
    
  • 想要描述:提取对象中共性的内容,对具体的抽象描述时,这些对象的共性有:姓名,年龄,性别,学习的功能等。映射到JAVA中,描述就是class定义的类,具体对象就是对应JAVA在对内存中建立的实体。
  • 例如:定义一个需求:描述汽车(颜色...等)。描述事物其实就是在描述事物的属性和行为。 该需求的类和对象的关系:如图:

Java基础-05-面向对象_第2张图片

属性对应类中的变量,行为对应类中的函数(方法)。其实定义类就是在描述事物,就是在定义属性和行为,属性和行为共同成为类中的成员(成员的变量和方法) Eg:

public class Demo1
 {
    public static void main(String []args)
    {
        //生产汽车,在Java中通过new操作符来完成
        //其实就是在对内存中产生一个实体
        Car c = new Car();    //c就是一个类类型变量
        //记住类类型变量指向对象
        //需求:将已有车的颜色改成蓝色,指挥该对象使用方法,在Java指挥就是:对象.对象成员/对象.对象方法
        c.color = "蓝色";
        c.run();
        Car c1 = new Car();
        c1.run();      //color :红色,4
    }
}

class Car 
{
    //描述颜色
    String color = "红色";
    //描述轮胎数
    int num = 4;
    //运行行为、
    void run ()
    {
        System.out.println(color+".."+num);
    }
}

以上程序可以用下图来表示:如图

Java基础-05-面向对象_第3张图片

Eg:思考一下以下例子

public class Demo1 {
    public static void main(String []args)
    {
        Car c = new Car();
        c.num = 5 ;
        Car c1 = c ;         //对象间赋值
        c1.color = "绿色";
        c.run();            //绿色  5
    }
}

class Car 
{
    //描述颜色
    String color = "红色";
    //描述轮胎数
    int num = 4;
    //运行行为
    void run ()
    {
        System.out.println(color+".."+num);
    }
}

输出的结果是绿色 5 原因如下图

Java基础-05-面向对象_第4张图片

4、面向对象(成员变量和局部变量)

成员变量和局部变量的区别:

  • 成员变量:作用于整个类中,并且生存于堆内存中。

  • 局部变量:作用于函数或语句中并且生存于栈内存中。

5、面向对象(匿名对象的应用)

什么是匿名对象:是对象的简化形式。

(1)、匿名对象使用方法一:当对象的方法只调用一次时,可以使用匿名对象来完成,这样写比较简化,但如果对一个对象进行多个成员调用,必须给这个对象起个名字。

Eg

public class Demo1 {
    public static void main(String []args)
    {
        //Car c = new Car();
        //c.num = 5 ;
        new Car().num = 5 ;
        new Car().color = "蓝色";
        new Car().run() ;   //结果是:红色..4  
    }
}

class Car 
{
    //描述颜色
    String color = "红色";
    //描述轮胎数
    int num = 4;
    //运行行为、
    void run ()
    {
        System.out.println(color+".."+num);
    }
}

为什么程序的结果不是红色..5或者是蓝色..4呢?而结果却是红色..4?

看图来观察原因:

Java基础-05-面向对象_第5张图片

从图中可以看出,用匿名对象去调用多个成员时,是相当于在调用时独立创建一个新的对象然后进行调用的,因此如果对一个对象进行多个成员调用,必须给这个对象起个名字。

(2)、匿名对象的使用方式二:可以将匿名对象作为实际参数进行传递。

Eg1:(正常没用使用匿名对象作为实际参数进行传递的例子)

public class Demo1 
{
    //需求:汽车修配厂,对汽车进行改装,将来的汽车都改成黑车,三个轮胎。
    public static void show (Car c)
    {
        c.num = 3 ;
        c.color = "黑色";
        c.run();
    }
    public static void main(String []args)         //主函数
    {
        Car q = new Car();
        show(q);
    }
}

class Car 
{
    //描述颜色
    String color = "红色";
    //描述轮胎数
    int num = 4;
    //运行行为、
    void run ()
    {
        System.out.println(color+".."+num);
    }
}

程序概况如图所示:

Java基础-05-面向对象_第6张图片

Eg2:(以下例子是匿名对象作实际参数)

public class Demo1 
{
    //需求:汽车修配厂,对汽车进行改装,将来的汽车都改成黑车,三个轮胎。
    public static void show (Car c)
    {
        c.num = 3 ;
        c.color = "黑色";
        c.run();
    }
    public static void main(String []args)
    {
        show(new Car());          //匿名对象作实际参数
    }
}

class Car 
{
    //描述颜色
    String color = "红色";
    //描述轮胎数
    int num = 4;
    //运行行为
    void run ()
    {
        System.out.println(color+".."+num);
    }
}

程序概况如图所示:

Java基础-05-面向对象_第7张图片

用匿名对象作函数实际参数传递的时候就相当于给函数show内的成员变量赋上匿名对象建立是的地址值。 小技巧:如何让实体变垃圾 Eg:

Car q = new Car();
q = Null;

6、面向对象(封装概述)

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

好处:

(1)、将变化隔离

(2)、便于使用

(3)、提高重用性

(4)、提高安全性

函数就是代码当中最小的封装。 原则:将不需要对外提供的内容都隐藏起来。把属性都隐藏,提供公共方式对其访问。 关键字private:私有

7、面向对象(封装Private)

Eg:

public class Demo1 
{
    public static void main(String []args)
    {
        Person p = new Person();
        p.age = 20;             //由于Person类中的age被定义为私有,所以对象不能直接访问类中的成员变量
        p.speak();
    }
}

class Person 
{
    int private age ;      //age被定义为私有的
    void speak()
    {
        System.out.println("age="+age);
    }
}

因此程序编译时会出现错误提示,说明age不能被对象p直接访问。

private:私有,权限修饰符:用于修饰类中的成员(成员变量,成员函数)。私有只在本类中有效,将age私有化之后,类以外即使建了对象也不能直接访问,但是人应该有年龄,就需要在Person类中提供对应访问age的方式。

注意:封装不是私有,私有仅仅是封装的一种表现形式。

Eg:

public class Demo1 
{
    public static void main(String []args)
    {
        Person p = new Person();
        p.haha(20);          //对象p调用成员方法来访问age
        p.speak();
    }
}

class Person 
{
    private int  age ; 
    public void haha (int a)         //定义了一个方法去访问类中的私有变量
    {
        age = a;
    }
    void speak()
    {
        System.out.println("age="+age);
    }
}

编程习惯:在类中,一般一个变量(属性)对应两个方法(函数):一个用来获取数值,一个用来设置。

之所以对外提供访问方式,就因为可以在访问方式中加入逻辑判断语句,对访问的数据进行操作,提高代码的健壮性。

Eg:

public class Demo1 
{
    public static void main(String []args)          //主函数
    {
        Person p = new Person();
        p.setAge(20);                      //调用Person类中的setAge方法,输入年龄
    }
}

class Person 
{
    private int  age ;              //age设置为private,即只能通过类中的方法来访问
    public void setAge(int a )       
    {
        if (a> 0 && a<130)               //在方法中设置if-else语句来进行判断,不在范围内的输出非法age
        {
            age = a;
            speak();
        }
        else System.out.println("非法age");
    }
    public int getAge()             //获取age变量值的方法
    {
        return age ;
    }
    void speak()
    {
        System.out.println("age="+age);
    }
}

8、面向对象(构造函数)

构造函数: 特点

(1)、函数名与类名相同。

(2)、不用定义返回值类型。

(3)、不可以写return语句。

作用:给对象进行初始化。 注意:

(1)、默认构造函数的特点。

(2)、多个构造函数是以重载的形式存在。

构造函数小细节:当对象一建立就会调用与之对应的构造函数,当一个类中没有一个构造函数时,系统会自动默认给该类加入一个空参数的构造函数(例如Person类中对象一建立就默认加入构造函数Person(){}),当在类中自定义了构造函数,系统就不加了。

Eg:

public class Demo1 
{
    public static void main(String []args)
    {
        Person p = new Person();           //建立一个新的Person类对象p
    }
}

class Person 
{
    Person()                    //自定义的构造函数
    {
        System.out.println("Person run!");
    }
}

程序结果:Person run!

该程序当新对象一建立,就马上调用自定义的构造函数Person(),然后输出Person run! Eg:

public class Demo1 
{
    public static void main(String []args)
    {
        Person p1 = new Person();
        Person p2 = new Person("lisi");
        Person p3 = new Person("wangwu",10);
    }
}

class Person 
{
    private String name ;
    private int age;    
    Person()
    {
        System.out.println("A:name = "+name+",age="+age);
    }
    Person(String n)
    {
        name = n;
        System.out.println("B:name = "+name+",age="+age);
    }
    Person(String n , int a)
    {
        name = n ;
        age = a;
        System.out.println("C:name = "+name+",age="+age);
    }
}

输出结果:

A:name = null,age=0
B:name = lisi,age=0
C:name = wangwu,age=10

若把以上程序中Person类中的构造函数Person(){}注销掉,程序会发生什么事情? 程序会提示编译不通过,因为原本在类中如果没有自定义构造函数,那么系统会默认定义一个构造函数,然后以上程序由于利用函数重载的技术进行了调用构造函数,因而存在了构造函数,所以系统再不会默认定义一个Person(){}的构造函数,因而如果注销了Person(){}构造函数,再输入该命令Person p1 = new Person();去建立一个新对象,程序编译失败。

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

  • 什么时候定义构造函数呢? 当分析事物时,该事物具备一些特性或者行为,那么将这些内容定义在构造函数中。

9、面向对象(构造代码块)

构造代码块:一般定义对象共性属性,作用给对象进行初始化,对象一建立就运行,而且优先于构造函数运行。 和构造函数的区别:构造代码块是给所有对象进行统一初始化,而构造函数是给对应对象初始化。

Eg:

public class Demo1 
{
    public static void main(String []args)
    {
        Person p1 = new Person();     //建立新Person对象

    }
}

class Person 
{
    private String name ;
    private int age;    
    Person()        //构造函数
    {
        System.out.println("Person run!");   
    }
    {
        System.out.println("Person code run!");  //构造代码块
    }
}

结果:

Person code run!
Person run!

可见当对象一建立构造代码块就运行,而且先于构造函数。

10、面向对象(this关键字)

注意:若把构造函数私有化,那么对象建立不成功,要注意! 思考以下代码:

public class Demo1 
{
    public static void main(String []args)
    {
        Person p1 = new Person("lisi");     //建立新Person对象并传入字符串lisi
        p1.speak();     
    }
}

class Person 
{
    private String name ;
    private int age;    
    Person(String name)        //构造函数重载,接收了主函数传来的字符串lisi
    {
        name = name;     //相当于自己赋值给自己,因为函数中的变量是局部变量,所以在
                                        //函数内使用的变量就是局部变量name,而不会自动出去外面寻找另外的name
    }        
    public void speak()
    {
        System.out.println("name = "+name+" age = "+age);
    }
}

所以程序结果是:

name = null age = 0

以上代码出现的问题如何解决? 我们可以把代码name = name ;改成this.name = name; 完整代码如下

public class Demo1 
{
    public static void main(String []args)
    {
        Person p1 = new Person("lisi");     //建立新Person对象并传入字符串lisi
        p1.speak();     
    }
}

class Person 
{
    private String name ;
    private int age;    
    Person(String name)        //构造函数重载,接收了主函数传来的字符串lisi
    {
        this.name = name;     //改进后的代码段
    }        
    public void speak()
    {
        System.out.println("name = "+name+" age = "+age);
    }
}

程序结果:

name = lisi age = 0

在代码中出现的this代表Person类的对象p。 this:看上去,用于区分局部变量和成员变量同名情况。this代表它所在函数所属对象的引用,简单说:哪个对象在调用this所在函数,this就代表哪个对象。

11、面向对象(this关键字的应用)

需求:给人定义一个用于比较年龄是否相同的功能,也就是是否是同龄人。

public class Demo1 
{
    public static void main(String []args)
    {
        Person p1 = new Person(20);          //新建一个p1对象,年龄是20
        Person p2 = new Person(30);          //新建另一个p2对象,年龄是30
        boolean b = p1.compare(p2);           //利用p1对象调用方法compare(),返回boolean的值赋值给b
        System.out.println(b);                          //打印b的值,布尔类型。
    }
}

class Person 
{
    private String name ;
    private int age;    
    Person(int age)        //构造函数重载
    {
        this.age = age;           //应用了this关键字
    }        
    //该函数判断两个人是否同龄
    public boolean compare (Person p)
    {
        if(this.age == p.age)          //if语句里应用了this关键字,p代表p2,而this代表引用了该方法的对象p1
        {
            return true;
        }
        else return false;
    }
}

程序结果:

false

this的应用总结:当定义类中的功能时,该函数内部要调用该函数的对象时,这时用this来表示这个对象,但凡本类功能内部使用到了本类对象,都用this来表示。

12、面向对象(this关键字在构造函数间调用)

之前例子中的改进。

public class Demo1 
{
    public static void main(String []args)
    {
        Person p1 = new Person("lisi",20);
        p1.speak();
    }
}

class Person 
{
    private String name ;
    private int age;    
    Person(String name)        //构造函数重载
    {
        this.name = name;     
    }        
    Person(String name,int age)
    {

        this(name);     //替代了代码this.name = name;这里的this代表Person类,即调用了构造函数Person("lisi")
        this.age = age;
    }
    public void speak()
    {
        System.out.println("name = "+name+" age = "+age);
    }
}

程序结果:

name = lisi age = 20

以上例子是证明this语句用于构造函数之间进行互相调用。 注意一个问题:this语句只能定义在构造函数的第一行,因为初始化要先执行。

你可能感兴趣的:(Java基础)