Java面向对象(一)

一、Java面向对象学习的三条主线

  1、Java类及类的成员。

    属性、方法、构造器、代码块、内部类。

  2、面向对象的三大特征。

    封装性、继承性、多态性。

  3、其他关键字。

    this、super、static、final、abstract、interface、package、import等。

二、面向对象与面向过程的区别

  面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

  可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。

  如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

  可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了多个步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。

  上述的内容是从网上查到的,觉得这个例子非常的生动形象,我就写了下来,现在就应该理解了他俩的区别了吧,其实就是两句话,面向对象就是高度实物抽象化、面向过程就是自顶向下的编程!

三、面向对象的两个要素

  1、类:对一类事物的描述,是抽象的、概念上的定义。

  2、对象:是实际存在的该类事物的每个个体,因此也被称为实例(instance)。

    >面向对象程序设计的重点是类的设计。

    >设计类就是设计类的成员。

四、类的设计

  1、设计类其实就是设计类的成员。

      常见的名称:

      属性 = 成员变量 = field = 域、字段

      方法 = 成员方法 = 函数 = method

      创建类的对象 = 类的实例化 = 实例化类

  2、类和对象的使用(面向对象思想落地的实现)

    1. 创建类、设计类的成员
    2. 创建类的对象。
    3. 通过“对象.属性”或“对象.方法”调用对象的结构。

  3、如果创建了一个类的多个对象,则每个对象都独立拥有一套类的属性(非static的)。如果我们修改一个对象的属性a,不会影响其他对象同一属性的值。

public class PersionTest {

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

        // 调用对象的属性、方法
        // 调用属性 “对象名.属性”
        p1.name = "Tom";
        p1.isMan = true;
        System.out.println(p1.name);
        System.out.println(p1.isMan);
        // 调用方法:“对象名.方法”
        p1.eat();
        p1.sleep();
        p1.talk("Chinese");
        
        //******************************
        Person p2 = new Person();
        System.out.println(p2.name);//null
        
        //****************************************
        //将P1变量保存的对象地址值赋给p3,导致p1和p3指向了堆空间中的同一个对象实体。
        Person p3 = p1;
        System.out.println(p3.name);//Tom
        p3.age = 10;
        System.out.println(p1.age);//10
    }
}

/*---------------------------------测试类---------------------------------------*/
class Person {
    // 属性
    String name;
    int age = 1;
    boolean isMan;

    // 方法
    public void eat() {
        System.out.println("人可以吃饭");
    }

    public void sleep() {
        System.out.println("人可以睡觉");
    }

    public void talk(String language) {
        System.out.println("人可以说话,使用的是" + language);
    }
}

五、对象的内存解析

    1. 堆(heap),此内存区域的唯一目的是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例及数组都要在堆上分配。
    1. 通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char、short、int、float、double、long)、对象引用(reference类型、他不等同于对象本身,是对象在堆内存的首地址)。方法执行完自动释放。
  1. 方法区
    1. 方法区(Method Area),用于存储已被虚拟机加载的类信息、 常量、静态变量、即时编译器编译后的代码等数据。

    4、解析图:

                

六、属性与局部变量对比

    1、属性(成员变量)与局部变量

        相同点:

            1、定义变量的格式相同

            2、先声明、后使用

            3、变量都有其对应的作用域

        不同点:

            1、在类中声明的位置不同

                属性:直接定义在一对{}内

                局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量。

            2、关于权限修饰符的不同

                属性:可以在声明属性时指明其权限,使用权限修饰符。

                    常用权限修饰符:public、protected、却省(默认)、private    ------->封装性

                局部变量:不可以使用权限修饰符。

            3、默认初始化值的情况

                属性:类的属性根据其类型都有默认的初始化值。

                    整形(byte、short、int、long):0

                    浮点型(double、float):0.0

                    字符型(char):0(或‘\u0000’)

                    布尔型(boolean):false

                局部变量:没有默认初始化

                    我们在调用局部变量之前一定要显示赋值

                    特别的:形参在调用时,我们赋值即可

            4、在内存中加载的位置不同。

                属性:加载到堆空间(非static)

                局部变量;加载到栈空间。

七、类中方法的声明和使用

    方法:描述类应该具备的功能。

    例如:Math类:sqrt()、random()、........

       Scanner类:nextXxx()......

       Arrays类:sort()、binarySearch()、toString()、equals().......

    1、举例:

       public void eat() {}            无返回值无形参

       public void sleep(int hour) {}         无返回值有形参

       public String getName() {}          有返回值无形参

       public String getNation(String nation) {}     有返回值有形参

    2、方法声明方式:

      权限修饰符   返回值类型    方法名 (形参列表){

          方法体

          }

    3、说明

      1、返回值类型:有返回值     无返回值

          (1)、如果方法有返回值,则必须在方法声明时指定返回值类型。同时在方法结束时使用return关键字返回指定类型的数据 “return  数据;”。

               如果方法没有返回值,则方法声明时用void表示返回值类型。没有返回值的方法中,就不需要使用return关键字。如果使用的话,只能“return;”表示结束此方法的执行。

          (2)、何时使用返回值?

              1、根据方法的功能需求设计相应的返回值。

      2、方法名:属于标识符,遵循标识符的规则和规范,“见名知意”。

      3、形参列表:方法可以声明0个,1个或者若干个形参。

          格式:权限修饰符  返回值类型   方法名(数据类型1  形参1,数据类型2   形参2  ,数据类型3   形参3···········){}

      4、方法体:方法功能的体现。

      5、return关键字的使用:

        1、适用范围:在方法体中。

        2、作用:1、结束方法。

              2、针对于有返回值类型的方法,使用“return  数据”返回所要的数据。

        3、注意点:return关键字后面不可以声明执行语句。

      6、方法的使用:

        1、方法的使用中可以调用当前类的属性或方法。

          方法A中又调用方法A:递归方法

        2、方法中不可以定义方法。

      7、方法的重载

        1、定义:在一个类中,允许存在一个以上的同命方法。只要他们的参数个数或参数类型不同即可。

              “两同一不同”:同一个类相同方法名

                      参数列表不同:参数个数不同、参数类型不同。

        2、举例:Arrays类中重载的sort()、binarySearch()........

        3、判断是否重载:

          跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!

        4、在通过对象调用方法时,如何确定某一指定方法:

            方法名------------>形参列表

public class OverLoadTest {

    public void getSum(int i, int j) {
        System.out.println(1);
    }

    public void getSum(double i, double j) {
        System.out.println(2);
    }

    public void getSum(String s, int i) {

    }

    public void getSum(int i, String s) {

    }
    
//    *************错误示范******************

//    public int getSum(int i, int j) {
//        return 0;
//    }
    
//    public void getSum(int m, int n) {
//        
//    }
    
//    private void getSum(int i, int j) {
//        
//    }
    
}

       8、可变个数的形参

          1、JavaSE5.0中提供了Varargs(variable number arguments)机制,允许直接定义能和多个实参相匹配的形参。

          2、具体使用:

              1、可变个数形参列表的格式:  数据类型...  变量名

              2、当调用可变个数形参的方法时,传入的参数个数可以是0个、1个或多个。

              3、可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。

              4、可变个数形参的方法与本类中方法名相同,形参类型为同类型数组的方法不构成重载,二者不能共存。

              5、可变个数形参在方法的形参列表中必须声明在末尾。

              6、在方法的形参列表中,最多只能声明一个可变个数形参。

public class MethodArgsTest {
    public static void main(String[] args) {
        MethodArgsTest m = new MethodArgsTest();
        m.show(123);
        m.show("hello");
        m.show("a", "b", "c");
        m.show();

    }

    public void show(int i) {

    }

    public void show(String s) {

    }

//    
    public void show(String... strs) {
        for (String string : strs) {
            System.out.println(string);// 输出:a b c
        }
    }

//    此方法与上面的方法无法构成重载,会产生冲突。
//    public void show(String[] strs) {
//        
//    }

    public void show(int i, String... strs) {

    }

//    The variable argument type String of the method show must be the last parameter
//    public void show(String... strs,int i) {
//
//    }

    
//方法的形参列表中最多只能有一个可变个数形参。
//    public void show(int i, int... c,String... strs) {
//
//    }

}

      9、方法参数的值传递机制

        1、如果变量是基本数据类型,此时变量保存的是数据值。

        2、如果变量是引用数据类型,变量保存的是数据的地址值。

public class ValueTransferTerst {
    public static void main(String[] args) {
        int m = 10;
        int n = m;
        System.out.println("m=" + m + "n = " + n);// m=10 n=10
        n = 20;
        System.out.println("m=" + m + "n = " + n);// m=10 n = 20

        // *************引用类型**********************
        Student s1 = new Student();
        s1.num = 1;
        Student s2 = s1;//s1和s2的地址值相同,都指向了堆空间中的同一个对象实体。
        System.out.println("s1.num = " + s1.num + ",s2.num = " + s2.num);//s1.num = 1,s2.num = 1
        s2.num = 3;
        System.out.println("s1.num = " + s1.num + ",s2.num = " + s2.num);//s1.num = 3,s2.num = 3
    }
}

      10、方法形参的值传递机制

         1、形参:方法声明时小括号内的参数。

            实参:方法调用时实际传递给形参的数据。

         2、值传递机制:

            1、如果参数是基本数据类型,此时实参赋给形参的时实参存储的数据值。

            2、如果参数是引用数据类型,此时实参赋给形参的是实参存储的地址值。

      11、递归方法

        1、定义:一个方法体内调用它自身。

        2、方法递归包含了一个隐式的循环,他会重复执行某段代码。但这种执行无需循环控制。

          递归一定要向已知的方向递归,否则这种递归就变成了无穷递归,类似于死循环。程序会抛出栈溢出异常(StackOverFlowException)。

八、对象数组的内存解析

  1、引用类型的变量(对象),只可能存储两类值,null或地址值 (含变量的类型)。

  2、堆栈图

    

 

 

 九、匿名对象的使用

  1、理解:通过new关键字创建对象,但没有变量名接收对象的地址值。

  2、特征:匿名对象只能调用一次。

  3、使用:如下。

public class InstanceTest {

    public static void main(String[] args) {
        Phone p = new Phone();
        p.sendEmail();//发邮件
        p.playGame();//玩游戏
        
        
        //匿名对象
//        new Phone().sendEmail();//发邮件
//        new Phone().playGame();//玩游戏
        
        new Phone().price = 1999;
        new Phone().showPrice();//手机价格为0.0
        
//        *********************************************************
        PhoneMall phoneMall = new PhoneMall();
        phoneMall.show(new Phone());//发邮件     玩游戏
    }
    
}

class PhoneMall{
    public void show(Phone phone) {
        phone.sendEmail();
        phone.playGame();
    }
}

class Phone{
    double price;
    public void sendEmail() {
        System.out.println("发邮件");
    }
    
    public void playGame() {
        System.out.println("玩游戏");
    }
    public void showPrice() {
        System.out.println("手机价格为"+price);
    }
    

}

 

posted @ 2021-03-15 22:45  早春的树  阅读(82)  评论(0编辑  收藏  举报