美文网首页
Java面向对象

Java面向对象

作者: 曾梦想仗剑天涯 | 来源:发表于2020-09-15 10:22 被阅读0次

    Java面向对象编程三个主要特征

    • 封装:内部操作对外部不可见,内部操作都不可直接使用才是安全的
    • 继承:在已有结构基础上,进行功能的扩充
    • 多态:是在继承的基础上扩充而来的概念,指的是类型的转换处理

    面向对象开发的三个步骤:

    • OOA 面向对象的分析
    • OOD 面向对象的设计
    • OOP 面向对象的编程

    类与对象

    • 类是对某一类事物的共性的抽象概念,而对象描述的是一个具体的产物。
    • 类是一个模板,而对象才是类可以使用的实例,先有类再有对象。
    • 在类中一般都会由两个组成:
      1. 成员属性(Field):有些时候为了简化称为属性
      2. 操作方法(Method):定义对象具有的处理行为

    类与对象的定义与使用

    /**
      定义类 class Person {}
      声明并实例化对象  类名称 对象名称 = new 类名称()
      Person per = new Person();
    */
    class Person {
      String name;
      int age;
      public void tell() {
        System.out.println("name:" + name);
        System.out.println("age:" + age);
      }
    }
    public class JavaDemo {
      public static void main(String [] arge) {
        Person per = new Person();
        per.name = "张三";
        per.age = 18;
        per.tell();
      }
    }
    

    对象内存分析

    • Java之中类属于引用数据类型,引用数据类型最大的困难之处在于要进行内存管理,同时在进行操作的时候也会发生内存关系的变化
    • 堆内存:保存对象的具体信息,在程序当中堆内存空间的开辟是通过new来完成的
    • 栈内存:保存的是一块堆内存的地址,通过地址找到堆内存,而后找到对象内容
    • 程序报错 NullPointerException 代表引用数据类型使用错误


      此图来源于李兴华老师

    对象引用分析

    • 类本身属于引用数据类型,既然是引用数据类型,那么就牵扯到内存的引用传递,所谓引用传递的本质:同一块堆内存空间可以被不同的栈内存所指向,也可以更换指向
    /**
      引用传递:Person per1 = new Person(); Person per2 = per1;
      输出结果 age: 80
    */
    public class JavaDemo {
      public static void main(String [] arge) {
        Person per1 = new Person();
        per1.name = "张三";
        per1.age = 18;
        Person per2 = per1;
        per2.age = 80;
        per1.tell();
      }
    }
    /**
      通过方法引用传递
    */
    public class JavaDemo {        
      public static void main(String [] arge) {
        Person per1 = new Person();
        per1.name = "张三";
        per1.age = 18;
        change()
        per1.tell();
      };
      public static void change(Person temp) {
        temp.age = 80;
      }
    }
    

    引用传递与垃圾产生分析

    • 引用传递如果处理不当,那么会造成垃圾的产生,即对堆内存处理不当将会产生垃圾
    • 垃圾空间指的是:没有任何栈内存指向的堆内存空间,所有的垃圾将被GC(Grabage Collector 垃圾收集器)不定期进行回收并且释放无用内存空间,但是如果垃圾过多,就会影响到GC的处理性能,从而降低整体的程序性能,所以实际开发当中,垃圾产生的越少越好
    /**
      per1(栈内存地址)指向new Person()
      per2(栈内存地址)指向new Person()
      两个指向的new Person() 不同
      per2 = per1 改变了per2指向
      那么per2在定义时指向的堆内存将会变成垃圾
    */
    public class JavaDemo {
      public static void main(String [] arge) {
        Person per1 = new Person();
        Person per2 = new Person();
        per1.name = "张三";
        per1.age = 18;
        per2.name = "李四";
        per2.age = 80;
        per2 = per1; 
        per2.age = 18;
        per1.tell();
      }
    }
    

    成员属性封装

    • 在类之中的组成就是属性与方法,一般而言方法都是对外提供服务的,所以是不会进行封装处理,而对于属性由于其需要较高的安全性,所以往往需要对其进行保护,这个时候就需要采用封装性对属性进行保护
    • 类中所有属性都必须使用private封装。并且属性要进行访问必须提供setter与getter方法。
    /**
      private关键字对属性进行封装
      private String name;
      private int age;
      属性一旦封装之后对外部将不能够直接访问
      可用setter getter获取/设置属性
    */
    public void setName(String n) {
     name =  n;
    };
    public String getName() {
      return name
    };
    per.setName("张三");
    String perName = per.getName();
    

    构造方法与匿名对象

    • 构造方法是实现实例化对象中的属性初始化处理。
    • 构造方法定义:
      1. 构造方法名称必须与类名称保持一致
      2. 构造方法不允许设置任何的返回值类型,即没有返回值定义
      3. 构造方法是在使用关键字new实例化对象的时候自动调用的
    /**
      public Person 即为构造方法
    */
    class Person {
      private String name;
      private int age;
      public Person(String n, int a){ 
        name = n; 
        age = a; 
      }
      public void tell(){
        System.out.println("姓名:"+ name +"年龄:"+ age);
      }    
    }
    public class JavaDemo {
      public static void main(String [] args) {
        Person per =newPerson("张三", 18);
        per.tell();
      }
    }
    /**
      Person定义对象的所属类型,类型决定了你可以调用的方法
      per 实例化对象的名称
      new 开辟一块新的堆内存空间
      Person(“张三”, 18)调用有参构造,Person()调用无参构造函数,一个类至少存在一个构造方法
    */
    Person per1 = new Person();
    Person per2 = new Person(“张三”, 18);
    
    • 程序编译器是根据代码结构进行编译处理,执行的时候是根据代码结构来处理
      如果构造方法上使用了void,那么此结构就与普通方法的结构完全相同了,这样编译器会认为此方法是一个普通方法,普通方法与构造方法最大的区别:构造方法是在类对象实例化的时候调用的,而普通方法是在类对象实例化之后调用
    • 构造方法本身就是一个方法,是方法就有重载性,构造方法的重载只需要考虑参数的类型和个数

    this关键字

    • 三类构造描述:
      • 当前类中的属性: this.属性
      • 当前类中的方法(构造方法,普通方法),thia(),this.方法名称()
      • 构造方法必须在实例化新对象的时候调用,所以“this()” 的语句只允许放在构造方法的首行
      • 构造方法互相调用时请保留有程序的出口,别形成死循环,造成递归调用
        描述当前对象
    • 使用this调用当前类中属性
      • 只要是访问本类中属性的时候,要加上"this"实现访问

    简单的Java类

    • 指的是可以描述某一类信息的程序类。例如一本书、一个人。这个类之中没有特别复杂的逻辑操作,只作为一种信息存储的媒介存在。
    • 简单Java类开发结构:
      1. 类名称一定要有意义,可以明确的描述某一类事物;
      2. 类之中的所有属性都必须使用private进行封装,同时封装后的属性必须要有setter和getter;
      3. 类之中可以提供无数的构造方法,但必须保留无参构造方法;
      4. 类之中不允许出现任何的输出语句,所有的内容获取必须返回;
    class Dept {
      private long deptNo;
      private String deptName;
      private String loc;
      public Dept() {};
      public Dept(long deptNo, String deptName, String loc) {
        this.deptNo = deptNo;
        this.deptName = deptName;
        this.loc = loc;
      };
      public String getInfo() {
        return "部门编号:" + this.deptNo + "、部门名称:" + this.deptName + "、部门位置:" + this.loc;
      };
      public void setDeptNo(long deptNo) {
        this.deptNo = deptNo;
      };
      public long getDeptNo() {
        return this.deptNo;
      };
      public void setDeptName(String deptName) {
        this.deptName = deptName;
      };
      public String getDeptName() {
        return this.deptName;
      };
      public void setLoc(String loc) {
        this.loc = loc;
      };
      public String getLoc() {
        return this.loc;
      };
    }
    public class JavaStudy {
      public static void main (String [] args) {
        Dept dept = new Dept(18, "技术部", "石家庄");
        System.out.println(dept.getInfo());
      }
    }
    

    static定义属性

    • static是一个关键字,主要是用来定义属性和方法,在一个类中,所有的属性一旦定义了实际内容,就会交由各自的堆内存空间进行保存。
    • static是一个公共属性,虽然可以通过对象进行访问,但是应通过最高代表(类)来进行访问,所以static属性可以通过类名称来直接调用。

    static属性虽然定义在类之中,但是不受到类实例化对象的控制,static属性可以在对象没有实例化的时候使用。

    static定义方法

    • static定义方法,同样可以直接通过类名称来调用。
      • static方法只允许调用static属性或static方法;
      • 非static方法允许调用static属性或static方法;
    • static在回避实例化对象调用并且描述公共属性的情况下才会考虑使用static定义方法或者属性

    static应用

    /**
      一个程序类,可以实现实例化对象个数的统计
      每一次创建新的实例化对象都可以实现一个统计操作
      实现属性自动命名处理
    */
    class Book {
      private String title;
      private static int count = 0;
      public Book () {
        this("NOTTITLE - " + count++);
      };
      public Book (String title) {
        this.title = title;
      };
      public void setTitle (String title) {
       this.title = title;
      };
      public String getTitle () {
        return this.title;
      };
    }
    public class JavaStudy {
      public static void main (String [] args) {
        System.out.println(new Book("Java").getTitle());
        System.out.println(new Book("JavaScript").getTitle());
        System.out.println(new Book().getTitle());
        System.out.println(new Book().getTitle());
      }
    }
    

    代码块

    • 在程序中使用“{}”定义的结构称为代码块,然后根据代码块出现的位置分为普通代码块、构造代码块、静态代码块、同步代码块。
    /**
      普通代码块:定义在一个方法中的代码块
      在一个方法中可以对结构拆分,防止相同变量互相影响
    */
    public class JavaStudy {
      public static void main (String [] args) {
        {
          int x = 10;
          System.out.println("x = " + x);
        }
        int x = 100;
        System.out.println("x = " + x);
      }
    }
    /**
      构造代码块:定义在一个类之中
      构造块会优先于构造方法执行,并且每一次实例化对象的时候都会调用构造块中的代码
    */
    class Person {
      public Person {
        System.out.println("构造方法");    
      }
      {
        System.out.println("构造块");
      }
    }
    /**
      静态代码块:用static定义的代码块
      分为主类中定义静态块,非主类定义静态块
      执行顺序 静态代码块>构造代码块>构造方法
      静态代码块只执行一次,主要是为类中静态属性初始化
    */
    class Person {
      static {
        System.out.println("静态代码块");
      }
    }

    相关文章

      网友评论

          本文标题:Java面向对象

          本文链接:https://www.haomeiwen.com/subject/mlvxyktx.html