面向对象

面向对象

1、面向过程和面向对象有什么区别?

从语言方面出发:
	对于C语言来说,是完全面向过程的。
	对于C++语言来说,是一半面向过程,一半是面向对象。(C++是半面向对象的)
	对于Java语言来说,是完全面向对象的。

什么是面向过程的开发方式?
	面向过程的开发方式主要的特点是:
		注重步骤,注重的是实现这个功能的步骤。
		第一步干什么
		第二步干什么
		....
		另外面向过程也注重实现功能的因果关系。
			因为A所有B
			因为B所以C
			因为C所以D
			.....
		面向过程中没有对象的概念。只是实现这个功能的步骤以及因果关系。
	
	面向过程有什么缺点?(耦合度高,扩展力差。)
		面向过程最主要是每一步与每一步的因果关系,其中A步骤因果关系到B
		步骤,A和B联合起来形成一个子模块,子模块和子模块之间又因为因果
		关系结合在一起,假设其中任何一个因果关系出现问题(错误),此时
		整个系统的运转都会出现问题。(代码和代码之间的耦合度太高,扩展力
		太差。)
			螺栓螺母拧在一起:耦合度高吗?
				这是耦合度低的,因为螺栓螺母可以再拧开。(它们之间是有接口的。)
			螺栓螺母拧在一起之后,再用焊条焊接在一起,耦合度高吗?
				这个耦合度就很高了。耦合度就是黏连程度。
				往往耦合度高的扩展力就差。
			
			耦合度高导致扩展力差。(集成显卡:计算机显卡不是独立的,是集成到主板上的)
			耦合度低导致扩展力强。(灯泡和灯口关系,螺栓螺母关系)
		
		采用面向过程的方式开发一台计算机会是怎样?
			这台计算机将没有任何一个部件,所有的都是融合在一起的。
			你的这台计算机是一个实心儿的,没有部件的。一体机。
			假设这台一体机的任何一个“部位”出问题,整个计算机就不能用了,
			必须扔掉了。(没有对象的概念。)

		采用面向对象的方式开发一台计算机会是怎样?
			内存条是一个对象
			主板是一个对象
			CPU是一个对象
			硬盘是一个对象
			然后这些对象组装在一起,形成一台计算机。
			假设其中CPU坏了,我们可以将CPU拆下来,换一个新的。

	面向过程有什么优点?(快速开发)
		对于小型项目(功能),采用面向过程的方式进行开发,效率较高。
		不需要前期进行对象的提取,模型的建立,采用面向过程
		方式可以直接开始干活。一上来直接写代码,编写因果关系。
		从而实现功能。

什么是面向对象的开发方式?
	采用面向对象的方式进行开发,更符合人类的思维方式。(面向对象成为主流的原因)
	人类就是以“对象”的方式去认识世界的。
	所以面向对象更容易让我们接受。

	面向对象就是将现实世界分割成不同的单元,然后每一个单元
	都实现成对象,然后给一个环境驱动一下,让各个对象之间协
	作起来形成一个系统。

	对象“张三”
	对象“香烟”
	对象“打火机”
	对象“吸烟的场所”
	然后将以上的4个对象组合在一起,就可以模拟一个人的抽烟场景。
	其中“张三”对象可以更换为“李四”
	其中“香烟”也可以更换品牌。
	其中“打火机”也可以更换。
	其中“吸烟的场所”也可以更换。

	采用面向对象的方式进行开发:
		耦合度低,扩展力强。

找一个合适的案例。说明一下面向对象和面向过程的区别?
	蛋炒饭:
		鸡蛋和米饭完全混合在一起。没有独立对象的概念。
		假设客户提出新需求:我只想吃蛋炒饭中的米饭,怎么办?
			客户提出需求,软件开发者必须满足这个需求,于是
			开始扩展,这个软件的扩展是一场噩梦。(很难扩展,耦合度太高了。)

	盖饭:
		老板,来一份:鱼香肉丝盖饭
		鱼香肉丝是一道菜,可以看成一个独立的对象。
		米饭可以看成一个独立的对象。
		两个对象准备好之后,只要有一个动作,叫做:“盖”
		这样两个对象就组合在一起了。

		假设客户提出新需求:我不想吃鱼香肉丝盖饭,想吃西红柿鸡蛋盖饭。
		这个扩展就很轻松了。直接把“鱼香肉丝”对象换成“西红柿鸡蛋”对象。

当我们采用面向对象的方式贯穿整个系统的话,涉及到三个术语:
OOA:面向对象分析
OOD:面向对象设计
OOP:面向对象编程
整个软件开发的过程,都是采用OO进行贯穿的。

实现一个软件的过程:
	分析(A) --> 设计(D) --> 编程(P)

在软件公司当中,一般同事与同事之间聊天,有的时候会突然说出来一个英语单词。
这种情况是很常见的。所以一些术语还是要知道的,不然会闹出笑话。

leader 领导/经理/组长
team 团队
PM 项目经理(整个项目的监管人)Project Manager

2、类和对象的概念

面向对象当中最主要“一词”是:对象。

什么是类?
	类实际上在现实世界当中是不存在的,是一个抽象的概念。
	是一个模板。是我们人类大脑进行“思考、总结、抽象”的一个
	结果。(主要是因为人类的大脑不一般才有了类的概念。)

	类本质上是现实世界当中某些事物具有共同特征,将这些共同
	特征提取出来形成的概念就是一个“类”,“类”就是一个模板。

	明星是一个类

什么是对象?
	对象是实际存在的个体。(真实存在的个体)

	宋小宝就是一个对象
	姚明就是一个对象
	刘德华就是一个对象
	....

	宋小宝、姚明、刘德华这3个对象都属于“明星”这个类。

在java语言中,要想得到“对象”,必须先定义“类”,“对象”是通过“类”
这个模板创造出来的。
	类就是一个模板:类中描述的是所有对象的“共同特征信息”
	对象就是通过类创建出的个体。

这几个术语你需要自己能够阐述出来:
	类:不存在的,人类大脑思考总结一个模板(这个模板当中描述了共同特征。)
	对象:实际存在的个体。
	实例:对象还有另一个名字叫做实例。
	实例化:通过类这个模板创建对象的过程,叫做:实例化。
	抽象:多个对象具有共同特征,进行思考总结抽取共同特征的过程。

	类 --【实例化】--> 对象(实例)
	对象 --【抽象】--> 类

类是一个模板,是描述共同特征的一个模板,那么共同特征包括什么呢?

	潘长江对象:
		名字:潘长江
		身高:165cm

		打篮球:非专业的,自己玩儿呢,无所谓了
		学习:考试80分

	姚明对象:
		名字:姚明
		身高:240cm
		打篮球:NBA专业球员,打篮球非常棒
		学习:考试100分

	共同特征包括哪些?
		名字、身高都属于名词(状态特征)
		打篮球、学习都属于动词(动作特征)
	
	类 = 属性 + 方法
	属性来源于:状态
	方法来源于:动作

	public class 明星类{
		//属性-->状态,多见于名词
		名字属性;
		身高属性;

		//方法-->动作,多见于动词
		打篮球方法(){
		
		}
		学习方法(){
		
		}
	}

	陈赓同学、何伟彬同学,他们俩有没有共同特征呢?
		有共同特征,就可以抽象一个类模板出来。
	
	可以定义一个学生类(Student)
	public class Student {
		// 属性
		// 姓名
		// 性别
		// 身高

		// 方法
		public .... sing(){
		
		}
		public .... dance(){
		
		}
		public .... study(){
		
		}
		....
	}

2.1类的定义

[修饰符列表] class 类名 {
//类体 = 属性 + 方法
// 属性在代码上以“变量”的形式存在(描述状态)
// 方法描述动作/行为
}

​ 注意:修饰符列表可以省略。

为什么属性是“以”变量的形式存在的?
答案:是因为属性对应的是“数据”,数据在程序中只能放到变量中。
结论:属性其实就是变量。

​ 变量的分类
​ 变量根据出现位置进行划分:
​ 方法体当中声明的变量:局部变量。
​ 方法体外声明的变量:成员变量。(这里的成员变量就是“属性”)

2.2对象创建和使用

类(java中定义的和我们自己定义的)是一个引用类型,使用有固定的三个步骤:

1.导包(找到我们要使用的东西)
            格式: import 包名.类名;
            注意:
                (1)java.lang包下的内容,不需要导包可以直接使用
                (2)如果当前类和要使用的类在同一个保重,也不需要导包
            导包快捷键: alt + 回车

2.创建对象:
​        数组的创建:
​            数据类型[] 数组名称 = new 数据类型[长度];

​        举例:
​            Scanner sc = new Scanner(System.in);
​            Random r = new Random();

​        格式:
​            类名 对象名 = new 类名(参数...);
​            Student stu = new Student();

3.对象的使用:(1)对象名称: 对象在堆内存空间的地址值
​        (2)成员变量的使用:
​            对象名称.成员变量名称
​            stu.name: 对象的name属性

​        (3)成员方法的使用:
​            对象名称.成员方法名称(参数列表...);
​            stu.eat(): 调用对象stu的eat方法

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

1.在类中的位置不同【重点】 
    成员变量:类中,方法外 
    局部变量:方法中或者方法声明上(形式参数)
    
2.作用范围不一样【重点】 
    成员变量:类中 
    局部变量:方法中
    
3.初始化值的不同【重点】 
    成员变量:有默认值 
    局部变量:没有默认值。必须先定义,赋值后再使用
    
4.在内存中的位置不同(了解) 
    成员变量:堆内存 
    局部变量:栈内存
    
5.生命周期不同(了解) 
    成员变量:随着对象的创建而存在,随着对象的消失而消失 
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
public class Person {
    //成员变量
    String name;//在该类的所有的成员方法内部都可以使用

    //成员方法
    /*
        下面是在定义方法show,内部使用的局部变量s和num,
        要保证在方法运行时必须有值才可以
     */
    public void show(String s) {//在方法定义时()中指定的变量: 形式参数,也叫作局部变量
        //方法内部定义变量:局部变量,只在show方法内部有效
        int num ;
        System.out.println(name);

        System.out.println(s);//hello

        //局部变量num,没有默认值: 不赋值不能使用的

        //num = 1000;

        //System.out.println(num);
    }


    public void method() {
        //错误: num和s是局部变量,只能在show方法内部使用
        //num = 10;
        //s = "hello";

        System.out.println(name);
    }
}

public class Demo01Person {
    public static void main(String[] args) {
        //创建Person类的对象
        Person p = new Person();

        System.out.println(p.name);//默认值: null


        //调用成员方法
        p.show("hello");
    }
}    

2.4对象和引用的区别

​ 对象是通过new出来的,在堆内存中存储。
​ 引用是:但凡是变量,并且该变量中保存了内存地址指向了堆内存当中的对象的。

2.5类与对象

/*
    定义手机Phone类,用来模拟现实中的手机事物
        成员变量:和以前定义变量相同,位置不同,在类中方法外
            品牌: String brand
            颜色: String color
            价格: int price

        成员方法:和以前定义方法格式相同,去掉static关键字
            打电话: void call(String who)
            发短信: void sendMessage(String who,String msg)

 */
/*
    这里定义了一个名称为Phone的类,用来描述手机事物,相当于模板/模型/图纸,
    不能直接使用,要想使用,必须根据模板/模型/图纸创建(如何创建一个具体的对象呢?)一个具体的手机对象才可以使用.
    抽象:
        抽取出现实事物中像的部分,相同的部分,相似的部分
 */
public class Phone {
    //成员变量
    String brand;//品牌
    String color;//颜色
    int price;//价格


    //成员方法
    //打电话
    public void call(String who) {
        System.out.println("正在给..."+who+"...打电话...");
    }

    //发短信
    public void sendMessage(String who, String msg) {
        System.out.println("正在给..."+who+"...发短息: "+msg);
    }
}

3.理解练习

动物之猫和狗练习
    需求:
    	猫类Cat
    		属性:
				color:毛的颜色
    			breed:品种
    		行为:
				eat():吃饭
    			catchMouse():抓老鼠
        狗类Dog
            属性:
        		color:毛的颜色
            	breed:品种
            行为:
        		eat():吃饭
            	lookHome():看家
    要求:
        1.按照以上要求定义Cat类和Dog类
        2.定义测试类,在main方法中创建该类的对象并给属性赋值
        3.调用成员方法,打印格式如下:
			花色的波斯猫正在吃鱼.....
            花色的波斯猫正在逮老鼠....
            黑色的藏獒正在啃骨头.....
            黑色的藏獒正在看家.....
public class Cat {
    //成员变量
    String color;//毛的颜色
    String breed;//品种

    //成员方法
    //吃饭
    public void eat() {
        System.out.println(color+"的"+breed+"正在吃鱼.....");
    }
    //抓老鼠
    public void catchMouse() {
        System.out.println(color+"的"+breed+"正在逮老鼠....");
    }
}
public class Dog {
    //成员变量
    String color;//毛的颜色
    String breed;//品种

    //成员方法
    //吃饭
    public void eat() {
        System.out.println(color+"的"+breed+"正在啃骨头.....");
    }
    //看家
    public void lookHome() {
        System.out.println(color+"的"+breed+"正在看家.....");
    }
}
public class Demo01CatAndDog {
    public static void main(String[] args) {
        //创建Cat类的对象
        Cat cat = new Cat();

        //给成员变量赋值
        cat.color = "花色";
        cat.breed = "波斯猫";

        //调用成员方法
        /*
            使用cat对象调用eat和catchMouse方法时,
            这两个方法内部使用的变量color和breed,
            是cat对象内部的color和breed
         */
        cat.eat();
        cat.catchMouse();
        System.out.println("-------------");

        //创建Dog类的对象
        Dog dog = new Dog();

        //给成员变量赋值
        dog.color = "黑色";
        dog.breed = "藏獒";


        //调用成员方法
        /*
            使用dog对象调用eat和lookHome方法时,
            这两个方法内部使用的变量color和breed,
            是dog对象内部的color和breed
         */
        dog.eat();
        dog.lookHome();
    }
}

4.private关键字

    发现问题:
        定义类时,虽然指定了成员变量的含义(比如:age代表年龄),
        但是却无法保证成员变量的取值在一个合理有效的范围之内
        比如:
            年龄age: 必须在[0,100]之间 age>=0 && age<=100

    解决方案: private关键字,private单词: 私有
        1.private关键字的使用:
            将需要保护的成员变量使用private关键字,修饰一把

        2.使用格式:
            (1)修饰成员变量: private 数据类型 变量名称;
            (2)修饰成员方法: private 返回值类型 方法名称(参数列表...){...}

        3.可以修饰的内容:
            (1)成员变量
            (2)成员方法
            (3)构造方法【以后讲】
            (4)内部类【以后讲】

         4.private修饰的成员的访问特点:
            (1)private修饰的成员(成员变量/成员方法),可以在本类(定义成员所在的类)中使用
            (2)private修饰的成员(成员变量/成员方法),不能在其它类中直接使用(对象名.成员变量名)

         5.private修饰成员后暴露新的问题:private修饰的成员(成员变量/成员方法),不能在其它类中直接使用(对象名.成员变量名)
            但是可以在其它类中通过set方法/get方法间接访问被private修饰的成员变量

            (1)为被private修饰的成员变量提供set方法: 作用是修改成员变量的值
                三要素:
                    a.方法名称: set+成员变量名称(第一个字母大写)
                    b.参数列表: 定义一个和成员变量类型相同的参数
                    c.返回值类型: void

                发现提供set方法后,仍然可以给成员变量随便赋值:
                    解决方案: 可以在方法内部添加逻辑判断,限制成员变量的取值

            (2)为被private修饰的成员变量提供get方法:作用是获取成员变量的值
                三要素:
                    a.方法名称: get+成员变量名称(第一个字母大写)
                    b.参数列表: 不需要
                    c.返回值类型: 需要获取值的成员变量的类型

public class Person02 {
    //成员变量
    String name;//姓名
    private int age;//年龄

    /*
        定义给成员变量age赋值的set方法: setAge
     */
    public void setAge(int a) {
        if (a >= 0 && a <= 100) {
            age = a;
        }
    }

    /*
        定义获取员变量age值的get方法: getAge
     */
    public int getAge() {
        return age;
    }


    //成员方法
    //展示信息的方法
    public void show() {
        System.out.println("姓名: "+name+", 年龄: "+age);

    }


}

public class Demo02Problem {
    public static void main(String[] args) {
        //创建Person01类的对象
        Person02 p = new Person02();

        //给成员变量赋值
        p.name = "灭绝师太";
        //错误: age被private修饰,其它类中不能直接使用(对象名.成员变量名)
        //p.age = 18;

        //调用成员方法setAge给成员变量age赋值
        p.setAge(18);

        //调用成员方法
        p.show();

        //给age重新赋值
        //错误: age被private修饰,其它类中不能直接使用(对象名.成员变量名)
        //p.age = 8848;

        //调用成员方法setAge给成员变量age赋值
        p.setAge(8848);


        //调用成员方法
        p.show();

        //给age重新赋值
        //错误: age被private修饰,其它类中不能直接使用(对象名.成员变量名)
        //p.age = -9999;

        //调用成员方法setAge给成员变量age赋值
        p.setAge(-9999);

        //调用成员方法
        p.show();

        //调用getAge方法,获取成员变量age的值
        int age = p.getAge();
        System.out.println("年龄是: "+age);
    }
}
                        

5.static关键字

static修饰的统一都是静态的,都是类相关的,不需要new对象。直接采用“类名.”访问。
当一个属性是类级别的属性,所有对象的这个属性的值是一样的,建议定义为静态变量。

6.this关键字

this代表当前对象,谁调用就代表谁

访问规则:

就近原则: 方法内部有,直接使用,方法内部没有,找成员变量

this关键字的作用

用来区分局部变量和成员变量同名的情况的

应用:

/*
    到目前为止,定义标准的Java类的要求:
        1.所有成员变量private修饰
        2.为每个成员变量通过set方法(修改成员变量的值)和get方法(获取成员变量的值)

    注意:
        set/get方法快捷键:
            alt + insert --> Getter and Setter --> 选定成员变量 --> ok
            右键/generate --> Getter and Setter --> 选定成员变量 --> ok
 */
public class Person04 {
    //成员变量
    private String name;//姓名
    private int age;//年龄

    //成员方法
    public void show() {
        System.out.println("姓名: "+name+", 年龄: "+age);
    }

    //setName方法: 给成员变量name赋值
    public void setName(String name) {
        this.name = name;
    }

    //getName方法:获取成员变量name的值
    public String getName() {
        return name;
    }
    
    //setAge方法: 给成员变量age赋值
    public void setAge(int age) {
        this.age = age;
    }

    //getAge方法: 获取成员变量age的值
    public int getAge() {
        return age;
    }    
}

public class Demo04UsePrivateThis {
    public static void main(String[] args) {
        //创建Person04类的对象
        Person04 p = new Person04();

        //调用set方法给成员变量赋值
        p.setName("张三");
        p.setAge(18);

        //调用成员方法show,展示信息
        p.show();

        //调用get方法获取成员变量的值
        String n = p.getName();
        int a = p.getAge();
        System.out.println("姓名: "+n+", 年龄: "+a);
    }
}

7.构造方法

7.1构造方法的介绍

创建对象的格式:
	类名 对象名 = new 类名();
	举例:
		Person05 p = new Person05();
        创建对象的过程(死的java规定的过程): new关键字 + 调用构造方法

    构造方法:
        1.作用:
            当使用new关键字创建对象后(对象中成员变量都是默认值),
            必须要通过调用构造方法完成对象成员变量的初始化赋值

        2.格式:
            修饰符 构造方法名称(参数列表...) {
                方法体;
                return ;
            }

        3.特点:
            (1)修饰符中没有static关键字
            (2)没有返回值类型,void都不能写
            (3)构造方法名称必须和类名称保持一模一样
            (4)参数列表根据需求确定
            (5)return后面不能跟具体的数据值,只能写return ;
                建议可以省略

        4.注意:
            (1)自己定义类时,如果没有自己定义任何构造方法,编译器会隐藏提供一个空参构造方法(没有参数)
            (2)自己定义类时,如果自己定义了任何一个构造方法,编译器不会在隐藏提供一个空参构造方法(没有参数)
            (3)构造方法也是方法,既然是方法,就可以重载

7.2构造方法的使用

public class Person05 {
    //成员变量
    private String name;//姓名
    private int age;//年龄

    //空参构造方法
    public Person05() {
        System.out.println("空参构造方法被调用了....");
    }

    //满参构造方法
    public Person05(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //给name赋值的构造方法: 不常用
    public Person05(String name) {
        this.name = name;
    }

    //给age赋值的构造方法: 不常用
    public Person05(int age) {
        this.age = age;
    }

    //成员方法
    public void show() {
        System.out.println("姓名: "+name+", 年龄: "+age);
    }

    //setName方法: 给成员变量name赋值
    public void setName(String name) {
        this.name = name;
    }

    //getName方法:获取成员变量name的值
    public String getName() {
        return name;
    }

    //setAge方法: 给成员变量age赋值
    public void setAge(int age) {
        this.age = age;
    }

    //getAge方法: 获取成员变量age的值
    public int getAge() {
        return age;
    }
}
public class Demo05Constructor {
    public static void main(String[] args) {
        //空参构造: 创建Person05类的对象
        Person05 p = new Person05();


        //调用set方法给成员变量赋值
        p.setName("张三");
        p.setAge(18);

        //调用成员方法show展示信息
        p.show();

        System.out.println("---------------");


        //满参构造: 创建Person05的对象
        Person05 p2 = new Person05("李四", 28);

        //调用成员方法show展示信息
        p2.show();
    }
}

8.代码块

语句块位置不同作用域执行时间
普通语句块{}方法内部方法内部调用方法时
构造块{}类内方法外对象创建对象时
静态块static{}类内加载类时

注意:静态块,仅在类的第一次使用时加载。构造块,先于构造器执行,每创建一个对象执行一次

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值