• 第五章,面向对象基础篇


    5.3 封装性
      • 为了解决属性必须封装且又必须访问的矛盾,只要是被封装的属性,必须通过setter和getter方法设置和取得。
      • 为前面类的私有属性加上getter和setter方法

    Public void setAge(int a){
      Age = a;
    }
    Public int getAge(){
      Return age;
    }

    setter方法可以加上检测代码检测输入的数据是否合法。


    5.4构造方法
      

    Person per = null;声明对象时不调用构造方法。
    Per = new Person();实例化对象时调用构造方法。

    • 构造方法也是可以重载的。只要每个构造方法的参数类型或参数个数不同,即可实现重载。


    5.5 匿名对象
    匿名对象只在堆内存中开辟空间,而不在栈内存的引用。

    new Person("cathy",30).tell(); //匿名对象

    5.6 实例讲解

    class Student{
      private String stuno;
      public Student(){
        public Student(String stuno){
          this.setStuno(stuno);
        }
      }
      public float sum(){
        return math+english;
      }
      public float avg(){
        return this.sum/3;
      }

    5.7 String
    • ==是用来进行地址比较的
    Str2 str3指向同一个空间,他们的地址值就是相同的。
    内容比较用equals,

    str2.equals(str3)
    “hello”.equals("hello"),一个字符串可以调用string类中的方法,说明一个字符串就是一个string类的匿名对象。
    • String str1 = “hello”;

    使用这种方式定义字符串有一个好处,就是如果一个字符串已经被一个名称所引用,则以后再有相同的字符串声明时,就不会再重新开辟空间。

    String str2 = “hello”; str2==str1.
    java中有个字符串池。这种设计叫共享设计,设计思路是,对象池中保存多个对象,新实例化的对象如果已经在池中定义了,则不再重新定义,指向已存在的实例空间。
    使用new关键字,无论如何都会重新开一个空间。
    对于字符串,就直接赋值,不要采用new。


    • 字符串的内容一旦声明不可改变。
    非要改变就用stringbuffer类。

    • String (char[] value)字符数组变字符串。这是一个构造方法
    char[] toCharArray() 字符串变字符数组。这是一个普通方法
    char charAt(int index)字符串中取出指定位置字符
    int length()字符串长度
    String trim() 清除左右两端空格
    String[] split(String regex) 按指定字符串拆分 

    IO操作中经常会遇到字符串与byte数组或char数组之间的转换操作。

    • length取得数组的长度。
    length()取得字符串的长度。

    5.8 引用传递及基本应用

      1.引用传递

    public class RefDemo02{
        public static void main(String args[]){
            String str1 = "hello" ;            // 实例化字符串对象
            System.out.println("fun()方法调用之前:" + str1) ;
            fun(str1) ;                        // 调用fun()方法
            System.out.println("fun()方法调用之后:" + str1) ;
        }
        public static void fun(String str2){        // 此处的方法由主方法直接调用
            str2 = "MLDN" ;                    // 修改字符串内容
        }
    };

     程序运行结果

    fun()方法调用之前:hello
    fun()方法调用之后:hello

    因为字符串的内容一旦声明是不可改变的,改变的只是其内存地址的指向。

    class Demo{
        String temp = "hello" ;        // 此处为了方便,属性暂时不封装
    };
    public class RefDemo03{
        public static void main(String args[]){
            Demo d1 = new Demo() ;    // 实例化Demo对象,实例化之后里面的temp=30 
            d1.temp = "world" ;        // 修改temp属性的内容
            System.out.println("fun()方法调用之前:" + d1.temp) ;
            fun(d1) ;
            System.out.println("fun()方法调用之后:" + d1.temp) ;
        }
        public static void fun(Demo d2){        // 此处的方法由主方法直接调用
            d2.temp = "MLDN";                        // 修改temp值
        }
    };

     

      2.接收本类的引用

    class Demo{                        // 定义Demo类
        private int temp  = 30 ;    // 声明temp属性并封装
        public void fun(Demo d2){    // 接收本类的引用
            d2.temp = 50 ;            // 直接通过对象调用本类的私有属性
        }
        public int getTemp(){        // getter
            return temp ;
        }
        public void setTemp(int t){    // setter
            temp = t ;
        }
    };
    public class RefDemo04{
        public static void main(String args[]){
            Demo d1 = new Demo() ;    // 实例化Demo对象
            d1.setTemp(50) ;        // 只能通过setter方法修改内容
            d1.fun(d1) ;            // 此处把Demo的对象传回到自己的类中
            System.out.println("temp = " + d1.getTemp()) ;
        }
    };

      3.person类中可以有一个书属性,这个属性可以是book类。book类中可以有主人属性,这个属性可以是person类

    class Person{            // 定义Person类
        private String name ;    // 姓名
        private int age ;        // 年龄
        private Book book ;        // 一个人有一本书
       private Person child; //一个人一个孩子,person类有一个属性,值是另一个person类。
    public Person(String name,int age){ this.setName(name) ; this.setAge(age) ; } public void setName(String n){ name = n ; } public void setAge(int a){ age = a ; } public String getName(){ return name ; } public int getAge(){ return age ; } public void setBook(Book b){ book = b ; } public Book getBook(){ return book ; } }; class Book{ // 定义Book类 private String title ; // 标题 private float price ; // 价格 private Person person ; // 一本书属于一个人 public Book(String title,float price){ this.setTitle(title) ; this.setPrice(price) ; } public void setTitle(String t){ title = t ; } public void setPrice(float p){ price = p ; } public String getTitle(){ return title ; } public float getPrice(){ return price ; } public void setPerson(Person p){ person = p ; } public Person getPerson(){ return person ; } }; public class RefDemo05{ public static void main(String arg[]){ Person per = new Person("张三",30) ; Book bk = new Book("JAVA SE核心开发",90.0f) ; per.setBook(bk) ; // 设置两个对象间的关系,一个人有一本书 bk.setPerson(per) ; // 设置两个对象间的关系,一本书属于一个人
        
    System.out.println("从人找到书 --> 姓名:" + per.getName()+";年龄:" + per.getAge() +";书名:" + per.getBook().getTitle() + ";价格:" + per.getBook().getPrice()) ; // 可以通过人找到书 System.out.println("从书找到人 --> 书名:" + bk.getTitle() + ";价格:" + bk.getPrice() + ";姓名:" + bk.getPerson().getName() + ";年龄:" + bk.getPerson().getAge()) ; // 也可以通过书找到其所有人 } };

        

    5.9 this 关键字

        1.可以使用this强调本类中的方法

      2.表示类中的属性

    public Person(String name){
      name=name;
    }
    Vs.
    public Person(String name){
      This.name=name;
    }

    3.调用本类的构造方法

    如果一个类中有多个构造方法,可以利用this关键字互相调用。

      

    public Person(){
        System.out.println("一个新的Person对象被实例化。")
    }
    public Person(String name, int age){
        this();
        this.name = name;
    }          

    使用this调用构造方法必须也只能放在构造方法的第一行。

    this调用构造方法是一定要留一个构造方法作为出口,即程序中至少存在一个构造方法不使用this调用其他构造方法。

    一般都将无参构造方法作为出口。

        4.表示当前对象

          

    class Person{
        public Person(){
            pass
        }  
        public boolean compare(Person per){
            Person p1 = this;
            Person p2 = per;
            //person对象中有一个方法compare,可以用传进来的per对象和当前对象作对比
        }
    }        

     

     5.10 static 关键字

      1.java中常用的内存区域

      • 栈内存空间:保存所有的对象名称(更准确的说是保存了引用的堆内存空间的地址)
      • 堆内存空间:保存了每个对象的具体属性内容
      • 全局数据区:保存static类型的属性
      • 全局代码区:保存所有的方法定义

      2.类属性调用

        类名称.static属性

        Person.country = "b city" 

      3.使用static声明方法

    public static String getCountry(){
        return country;
    }

    4.使用static属性统计一个类产生了多少个实例化对象

    5.使用static为对象进行自动的编名操作

    6.程序中的System.exit(1)表示系统退出,只要在exit()方法中设置一个非零的数字,则系统执行到此语句之后将退出系统。

    7.如果一个方法要由主方法直接调用,则必须按以下格式声明:“punlic static 方法的返回值类型,方法名称(参数列表){}”。因为主方法是静态方法,而静态方法是不能调用非静态方法的,所以之前的方法声明处才必须加上static关键字。

     

    5.11 代码块

      1.普通代码块

      2.构造块

        构造块是直接写在类中的代码块,构造块优先于构造方法执行,每次实例化对象都会执行构造块中的代码。

    class Demo{
        {
            System.out.println("定义构造块");
        }
        public Demo(){
            System.out.println("构造方法");
        }
    }    

       3.静态代码块

        使用static声明的代码块。静态代码块优先于主方法执行,而在类中定义的静态代码块会优先于构造块执行,而且不管有多少个对象产生,静态代码块只执行一次。

    class Demo{
        static{
            System.out.println("静态代码块");
        }
    }

        静态代码块的妙用:静态代码块优先于主方法执行,那么就可以直接使用静态代码块而不使用主方法向屏幕上打印hello world了。成功打印hello world后,会爆找不到主方法的异常。解决办法是,在程序输出完hello world之后直接让程序退出即可。

    5.12 构造方法私有化

      1.对构造方法进行封装

        

    class Singleton{
        private Singleton(){
        }//此处将构造方法进行封装
    }
    public class SingleDemo02{
        public static void main(String args[]){
            Singleton s1 = null; //可以声明对象
            s1 = new Singleton();//错误,无法实例化
        }
    }

       解决方法

    class Singleton{
        //在内部产生本类的实例化对象,将属性封装
        private static Singleton instance = new Singleton();
        private Singleton(){ //将构造方法封装
        }
        public static Singleton getInstance(){ //通过静态方法取得Singleton类的实例
            return instance;
        }
    }
    public class demo{
      public static void main(String args[]){
        Singleton s1 = Singleton.getInstance();
        
    Singleton s2 = Singleton.getInstance();   
      }
    }

     instance,s1,s2 都指向同一个堆内存,不管有多少个对象,实际上只有一个实例。

    在设计模式中将这样的设计成为单例设计模式,及无论程序怎样运行,Singleton类永远只会有一个实例化对象存在。


    5.13 对象数组  
      1.对象数组的声明
        类 对象数组名称[] = new 类[数组长度];
    Person per[] = new Person[3];
    per[0] = new Person("cathy");
    per[1] = new Person(“tom”); 
    //分别为数组中的每个元素初始化,每一个都是对象,都需要单独实例化。
    
    
    
    
    
    //声明一个对象数组,里面有三个对象,使用静态初始化方式
    Person per[] = {new Person("张三"),new Person("李四"),new Person("王五")};
    
    

     5.14 内部类

      1.使用static定义内部类

        用static定义的内部类变成了外部类,用static声明的内部类不能访问非static的外部类属性。(在实际应用中用的不多,但是不代表没有价值。http://bbs.csdn.net/topics/350021609)

        内部类的第一个好处就体现出来了——隐藏你不想让别人知道的操作,也即封装性。
        内部类的第二个好处——一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量!   

      2.在外部访问内部类

        外部类.内部类 内部类对象 = 外部类.new 内部类();    
        Outer.Inner in = out.new Inner();
         

      3.在方法中定义内部类

          在方法中定义的内部类不能直接访问方法中的参数,如果方法中的参数想要被内部类所访问,参数钱必须加上final关键字。

          

    class Outer{        // 定义外部类
        private String info = "hello world" ;    // 定义外部类的私有属性
        public void fun(final int temp){        // 定义外部类的方法
            class Inner{                        // 在方法中定义的内部类
                public void print(){                // 定义内部类的方法
                    System.out.println("类中的属性:" + info) ;        // 直接访问外部类的私有属性
                    System.out.println("方法中的参数:" + temp) ;
                }
            };
            new Inner().print() ;                // 通过内部类的实例化对象调用方法
        }
    };
    public class InnerClassDemo05{
        public static void main(String args[]){
            new Outer().fun(30) ;    // 调用外部类的方法
        }
    };

    实例

      如果觉得分析类有困难,可以先把基本功能做完,做完之后对一些输入的数据进行验证,再把主方法中的代码尽可能减少,然后再去考虑代码的可重用性。

    本章要点

      如果一个对象没有被实例化而直接使用,则使用时会出现空指向异常。

      类属于引用数据类型。进行引用传递时,传递的是堆内存的使用权。

      使用构造方法实例化string时产生两个实例化对象,其中一个是垃圾空间。

      如果需要限制类对象的产生可以将构造方法私有化。一旦将构造方法私有化,在类的外部就不能new新对象,只能在类的内部创建好一个对象然后调用这个对象。这样就限制了对象的产生。

      对象数组的使用要分为声明数组和为数组开辟空间两步。开辟空间后数组中的每个元素的内容都是null。

      在方法中声明的内部类要想访问方法的参数,则参数前必须加上final关键字。因为方法的变量属于局部变量,离开该方法,变量就失去了作用,也就会自动被消除,内部类却不会离开所在方法是就失去作用。

     
  • 相关阅读:
    Oracle 删除某个用户下的所有对象,执行需谨慎
    ORACLE常用性能监控SQL
    mysql千万级大数据SQL查询优化
    qt小例子:实现阿里云物联网设备登录信息计算器
    mqtt协议
    亚马逊物联网平台c-sdk的使用
    esp32-cam开发环境搭建
    qt小例子:实现选值框和滑块同步变化
    在qt5中使用qtmqtt库
    将short类型转换为char类型
  • 原文地址:https://www.cnblogs.com/CATHY-MU/p/7807984.html
Copyright © 2020-2023  润新知