zoukankan      html  css  js  c++  java
  • 大数据JAVA基础第七天

    1.面向对象编程思想:“类”的引入

    前面我们学习过数组,当需要多次遍历数组时,我们可以将遍历的代码封装到方法中,需要遍历时,就调用相应的方法即可,提高代码的复用性。

    在对数组遍历的基础上继续增加需求,比如获取最值,数组逆转等,同样需要将这些功能封装到相应的方法中。这样继续封装会发现方法越来越多,于是就想能不能将这些方法继续进行封装呢?

    在前面的学习过程中,我们知道“类”是可以存放方法的(虽然目前还不清楚如何去设计一个完整的类,但最起码知道,类中是可以存放多个方法的),比如:main方法,自定义的add方法,show方法,sop打印方法等。所以,我们就考虑使用“类”来封装多个方法,将来有需要再对数组做相关的操作时,不是直接去找自定义的方法,而是先找到封装了这个方法的类,然后使用这个类中的方法。这就是面向对象思想的编程方式。

    从面相对象编程的角度考虑,类就是对多个方法的封装,当然,在类中除了方法,还有方法需要用到的一些变量等

    • 功能的封装==>方法
    • 多个方法和相关变量的封装==>类

    当你在编程过程中,想实现一个功能,不是直接在main方法外边去定义方法,而是想到先去定义一个“类”的时候,你已经具备了面向对象的编程思想。

    2.面向过程思想概述

    之前如果想要完成一个需求,一般的步骤是:首先是搞清楚要做什么,然后再分析怎么做,最后我们再写代码实现

    那么什么是面向过程开发呢?所谓的面向过程开发,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。

    面向过程的代表语言:C语言

    3.面向对象思想概述

    当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高。可随着需求的更改,功能的增多,发现需要面对每一个步骤很麻烦了,这时就开始改进,能不能把这些步骤和功能再进行封装,封装时根据不同的功能,进行不同的封装,功能类似的,或者有关联关系的封装在一起,这样结构就清晰了很多。用的时候,找到对应的类就可以了。这就是面向对象的思想。接下来我们看看面向对象到底是什么?

    假设有一个任务:写一个功能完整的Java程序,然后把这个程序部署到测试环境中

    仔细分析这个任务,发现需要完成这个任务的话,应该有两个动作:

    • 写程序
    • 部署到测试环境

    如果按照面向过程的编程思想的话,应该编写两个函数,分别用来实现上面提到的两个功能,然后依次调用这些函数,当这两个函数执行完了之后,整个任务就完成了。

    如果使用面向对象的思想编程的话,就把功能分解,交给不同的“对象”去完成。

    对象:可以暂时理解成具有某些功能的一个综合体

    例如,上面的任务中,涉及到了两个任务,写代码和部署程序,那么就去找哪个对象具有这样的功能,直接调用它们相应的方法就可以了

    整个过程如下:

    首先考虑谁会写代码,谁会部署程序,然后分别去找他们

    找到对象1 --> 写代码 --> 完成

    找到对象2 --> 部署程序 --> 完成

    --> 整个任务完成

    比如,有如下三个人,每个人都有自己的功能:使用伪码体现

    张三{

       Public void  部署程序(){

            System.out.println("部署java程序");

       }

    }

    李四{

       Public  void 写代码(){

            System.out.println("写java代码")

       }

    }

    小明{

       Public void 玩游戏(){

            System.out.println("玩游戏")

       }

    }

    第三个人不具有想要使用的功能,所以不会用到

    另外还有一个人,负责总指挥,调度每个人执行的先后顺序等

    老板{

        Public static void main(String[] args){

            李四.写代码();

           张三.部署程序 ();

           ...

        }

    }

    从以上的概述可以得出这样的结论:

    面向过程:强调的是过程,每个过程及实施都要自己一步一步去实施,考虑的事情比较多

    面向对象:强调的是对象,需要某些功能的时候,去找具有这样功能的对象,然后由对象去调用功能

    4.面向对象思想的特点

    • 是一种更符合我们思想习惯的思想
    • 可以将复杂的事情简单化,不必考虑执行的每一个细节,只从宏观上把握
    • 将我们从执行者变成了指挥者

    5.类和对象的含义

    • 对象:就是一个具体的事物,它有自己的属性和行为

        比如:一只狗,它有属性:颜色,体重,品种,它有行为:跑,叫,看家等等

        比如:一个手机,它有属性:颜色,价格,品牌等,它有行为:打电话,发短信等

        比如:笔记本电脑,它有属性:品牌,价格,内存大小,它有行为:开机,关机,播放音乐,可以打字等等

    • 类:同一种事物的抽象,将它们共同的属性和行为抽象出来,就是类

    比如前面说的狗,可以抽象出来一个犬类,手机,可以抽象出一个手机类,在代码中就是用关键字class定义类

    6.类与对象关系

    类:是一组相关的变量和方法的集合,是一个抽象的概念。

    对象:是类实例化创建出来的,是“类”这个概念的具体表现形式

    7.类的定义

    //学生类,现实世界中“学生”也是一个抽象概念,它是:所有的学生都有的共同点

    //在Java中定义类,就是将这些共同点用class类模拟出来

    class Student {

        //姓名

        String name;

        //年龄

        int age;

        //地址

        String address;

       

        //所有学生都有“学习”这样的行为,在类中就是定义学习这样的方法

        public void study() {

           System.out.println("学习");

        }

       

        //吃饭的方法

        public void eat() {

           System.out.println("吃饭");

        }

       

        //睡觉的方法

        public void sleep() {

           System.out.println("睡觉");

        }

    }

    类定义举例:

    //手机类

    //现实世界中,“手机”是一个抽象概念,

    //在Java中模拟手机这个事物的话,就可以定义一个类,这个类拥有手机的属性和行为

    class Phone {

        //品牌

        String brand;

        //价格

        int price;

        //颜色

        String color;

       

        //打电话的方法

        public void call(String name) {

           System.out.println("给"+name+"打电话");

        }

        //发短信的方法

        public void sendMessage() {

           System.out.println("发短信");

        }

        //玩游戏的方法

        public void playGame() {

           System.out.println("玩游戏");

        }

    }

    8.实例:自定义手机类,并在测试类中测试其中的变量和方法

    class Phone {

        //品牌

        String brand;

        //价格

        int price;

        //颜色

        String color;

        //打电话的方法

        public void call(String name) {

           System.out.println("给"+name+"打电话");

        }

       

        //发短信的方法

        public void sendMessage() {

           System.out.println("发短信");

        }

        //玩游戏的方法

        public void playGame() {

           System.out.println("玩游戏");

        }

    }

     

    class PhoneDemo {

        public static void main(String[] args) {

           //创建手机对象

           //类名 对象名 = new 类名();

           Phone p = new Phone();

           //直接输出成员变量值

           System.out.println(p.brand+"---"+p.price+"---"+p.color);

           //给成员变量赋值

           p.brand = "华为";

           p.price = 100;

           p.color = "灰色";

           //再次输出

           System.out.println(p.brand+"---"+p.price+"---"+p.color);

           //调用方法

           p.call("佟湘玉");

           p.sendMessage();

           p.playGame();

        }

    }

    9.实例变量和局部变量

    定义:

    实例变量:属于类的实例对象,没有static修饰的,目前接触到的成员变量都是实例变量

    局部变量:属于方法的变量,只在方法内有效

     

    区别:

    在类中的位置不同

    实例变量 在类中,并且在方法外定义

    局部变量 方法内或者方法声明上(形参)定义

    在内存中的位置不同

    实例变量 堆内存(属于对象)

    局部变量 栈内(属于方法)

    生命周期不同

    实例变量 随着对象的存在而存在,随着对象的消失而消失

    局部变量 随着方法的调用而存在,随着方法的调用完毕而消失

    初始化值不同

    实例变量 有默认的初始化值(0/false/null)

    局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。

    举例:验证局部变量的作用范围和必须初始化才能使用

    10.

    /*

    局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

    */

    class Variable {

        //成员变量

        //int num = 10;

        int num; //成员变量有默认值0/false/null

        public void show() {

           //int num2 = 20; //局部变量

           //可能尚未初始化变量num2

           //int num2; //没有默认值,只能先赋值,之后才能使用

           int num2 = 20;

           System.out.println(num2);

           //方法内使用的变量采用就近原则:方法内没有,就去找成员变量

           System.out.println(num);

        }

    }

     

    class VariableDemo {

        public static void main(String[] args) {

           Varialbe v = new Varialbe();

           System.out.println(v.num); //访问成员变量

           v.show();

        }

    }

    11.形式参数问题

    • 基本类型作为形式参数:传值,实际上就是把实参的值拷贝一份给形参,形参不论怎么改动,都不会影响到实参的值
    • 引用类型作为形式参数:传递的是实参所指向的实例对象或者数组,即:传递的是实参的引用(地址值),形参和实参具有相同的引用,所以,形参对引用的改动能立即从实参上看到

    /*

        形式参数的问题:

           基本类型:形式参数的改变不影响实际参数

           引用类型:形式参数的改变直接影响实际参数

    */

    //形式参数是基本类型

    class Demo {

        public int sum(int a,int b) {

           return a + b;

        }

    }

     

    //形式参数是引用类型

    //先自定义一个类,有一个实例方法show

    class Student {

        public void show() {

           System.out.println("学习");

        }

    }

     

    class StudentDemo {

        //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里需要的是该类的对象。

        public void method(Student s) {

    //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();

           s.show();

        }

    }

     

    class ArgsTest {

        public static void main(String[] args) {

           //形式参数是基本类型的调用

           Demo d = new Demo();

           int result = d.sum(10,20);

           System.out.println("result:"+result);

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

          

           //形式参数是引用类型的调用

           //需求:我要调用StudentDemo类中的method()方法

           StudentDemo sd = new StudentDemo();

           //创建学生对象

           Student s = new Student();

           sd.method(s); //把s的地址给到了这里

        }

    }

    12.匿名对象

    匿名对象:就是没有名字的对象,是对象的一种简化表示形式

    匿名对象的两种使用情况

    • 对象调用方法仅仅一次的时候,多次调用的时候,不适合用匿名对象
    • 作为实际参数传递可以使用匿名对象

    /*

        匿名对象:就是没有名字的对象。

        匿名对象的应用场景:

           A:调用方法,仅仅只调用一次的时候。

               注意:调用多次的时候,不适合。

               这种匿名调用有什么好处吗?

               有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。

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

    */

    class Student {

        public void show() {

           System.out.println("我爱学习");

        }

    }

     

    class StudentDemo {

        public void method(Student s) {

           s.show();

        }

    }

     

    class NoNameDemo {

        public static void main(String[] args) {

           //带名字的调用

           Student s = new Student();

           s.show();

           s.show();

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

           //匿名对象

           //new Student();

           //匿名对象调用方法

           new Student().show();

           new Student().show(); //这里其实是重新创建了一个新的对象

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

           //匿名对象作为实际参数传递

           StudentDemo sd = new StudentDemo();

           //Student ss = new Student();

           //sd.method(ss); //这里的s是一个实际参数

           //匿名对象

           sd.method(new Student());

           //再来一个,两个都是匿名对象

           new StudentDemo().method(new Student());

        }

    }

    13.封装概述

    封装概述

    封装是面向对象编程的三个重要特征之一,其余两个是多态和继承。

    封装指的是隐藏对象的属性和实现细节,不允许外部直接访问对象的内部信息,而是通过该类提供的方法来实现对内部信息的访问。

    封装是对现实世界的模拟,在现实世界中,对象的状态信息都被隐藏在对象的内部,外界无法直接操作和访问,例如一个人的年龄,是逐年增长的,假如暴露给外界的话,有可能会被外界修改。

    对一个类或者对象的良好封装,可以达到以下的效果:

    好处:

    • 隐藏实现细节,
    • 让使用者只能通过事先预定的方法来访问数据,从而可以在这个方法内加入逻辑控制,限制对成员变量的不合理访问
    • 可以进行数据检查,从而有利于保证对象信息的完整性
    • 便于修改,提高代码的可维护性

    为了实现良好的封装,需要从以下两个方面来考虑

    • 把对象的实例变量和实现细节隐藏起来,不允许外界直接访问
    • 把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作

    14.

    使用一个关键字private来修饰成员变量,外界就不能对它直接访问了,想要使用它的话,就必须提供公开的方法来对它进行访问,在这个方法中,就可以加入一些逻辑判断了,例如:

    /*

        定义一个学生类:

           成员变量:name,age

           成员方法:show()方法

        我们在使用这个案例的过程中,发现了一个问题:

           通过对象去给成员变量赋值,可以赋值一些非法的数据。

           这是不合理的。

           应该是这个样子的:在赋值之前,先对数据进行判断。

           判断到底在哪里做比较合适呢?

           StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。

           所以,这个判断应该定义在Student类中。

           而我们在成员变量的位置可不可以进行数据判断呢?

           是不可以的,因为做数据校验,必须要依靠一些逻辑语句。

           逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法来对数据进行校验。

        按照我们前面的分析,我们给出了一个方法进行校验。

        但是呢,它偏偏不调用方法来赋值,还是直接赋值了,

        这样我们的方法就没有起到作用。

        我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。

        怎么去强制要求不能直接使用成员变量呢?

        针对这种情况,Java就提供了一个关键字 private

        private:私有的。可以修饰成员变量和成员方法。

        注意:被private修饰的成员只能在本类中访问。

        其实我讲到现在讲解的是一个封装的思想。

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

    */

    class Student {

        //姓名

        String name;

        //年龄

        private int age;

        //写一个方法对数据进行校验

        /*

           返回值类型:void

           参数列表:int a

        */

    //age变量是私有的变量,在外界不能直接访问,但是类内部的方法却可以访问

    //在外界通过访问这个公共方法,间接的访问到了私有的成员变量

    //并且在方法内部还可以加入逻辑判断

        public void setAge(int a) {

           if(a < 0 || age > 150) {

               System.out.println("年龄值非法");

           }else {

               age = a;

           }

        }

        //show()方法,显示所有成员变量值,show()方法是公有的,所以能被外界直接访问

        //由于show()方法是在类中定义的,所以本类中的所有变量都是可以被它访问的

        //这样达到了间接访问的效果

        public void show() {

           System.out.println("姓名:"+name);

           System.out.println("年龄:"+age);

        }

    }

    class StudentDemo {

        public static void main(String[] args) {

           //创建学生对象

           Student s = new Student();

           s.show();//默认值

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

           //给成员变量赋值

           s.name = "林青霞";

           //s.age = 27;

           s.setAge(27);

           s.show();

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

           //给age赋值

           //s.age = -27; //这个数据是不合理的

           //通过方法给值

           s.setAge(-27);

           s.show();

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

        }

    }

    一旦将成员变量定义成private的,就不能直接访问了,比如:

    Student s = new Student();

    System.out.println(s.age);//error

    15.private关键字

    private关键字:

    • 是一个权限修饰符。
    • 可以修饰成员(成员变量和成员方法)
    • 被private修饰的成员只能本类中才能访问。

    private最常见的应用:

    • 把成员变量用private修饰
    • 提供对应的getXxx()/setXxx()方法,这样在类的外部就可以通过公有的方法对这些私有变量进行访问了

    一个标准的使用案例

    class Demo {

        //int num = 10;

        //用private修饰,只能在类中进行访问

        private int num = 10;

        public void show() {

           System.out.println(num);

        }

    //私有方法,只能在类中进行调用

        private void method() {

           System.out.println("method");

        }

        public void function() {

           method();

        }

    }

     

    class PrivateDemo {

        public static void main(String[] args) {

           Demo d = new Demo();

           //不能访问私有的成员变量

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

           d.show();

           //不能访问私有的成员方法

           //d.method();

           d.function();

        }

    }

  • 相关阅读:
    (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row
    (二叉树 BFS) leetcode513. Find Bottom Left Tree Value
    (二叉树 BFS DFS) leetcode 104. Maximum Depth of Binary Tree
    (二叉树 BFS DFS) leetcode 111. Minimum Depth of Binary Tree
    (BFS) leetcode 690. Employee Importance
    (BFS/DFS) leetcode 200. Number of Islands
    (最长回文子串 线性DP) 51nod 1088 最长回文子串
    (链表 importance) leetcode 2. Add Two Numbers
    (链表 set) leetcode 817. Linked List Components
    (链表 双指针) leetcode 142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/xiejiajun/p/6597477.html
Copyright © 2011-2022 走看看