美文网首页
7-16笔记-面向对象之对象和类

7-16笔记-面向对象之对象和类

作者: 须臾之北 | 来源:发表于2018-07-16 22:01 被阅读6次

    7月16号笔记

    今天的主要内容:

    • 对象和类的学习——联系类的构造技巧
    • 数组学习——for-each
    • LocalDate的学习
    • 关键字的学习——final/static/this
    • 工厂方法的学习【重点】
    • 类的设计技巧

    1. 数组的学习

    • 数组定义:

      int[] arr = new int[]{1,3,5,8,9,11};

    • java.util.Arrays类的使用

      • Arrays.toString(type[] a);

      • Arrays.copyOf(type[] a,int length);

      • Arrays.sort(type[] a);

    • TestArray

        import java.util.Arrays;
    
        public class TestArray{
            public static void main(String[] args){
                
                //数组的定义:
                int[] arr = new int[]{1,3,5,8,9,11};
                
                //Arrays.toString(type[] a);
                String arrString = Arrays.toString(arr);
                System.out.println("arr : " + arrString);
                
                //Arrays.copyOf(type[] a,int length);
                int[] b = Arrays.copyOf(arr,arr.length);
                
                //Arrays.sort(type[] a)
                Arrays.sort(b);
                
                //for-each遍历数组
                System.out.print("After sort : ");
                for(int element:b){
                    System.out.print(element + "  ");
                }
                
                System.out.println("\n");
            }
        }
        /*
        在JDK1.8中输出结果为:
        -------------------------------
        arr : [1, 3, 5, 8, 9, 11]
        After sort : 1  3  5  8  9  11
        -------------------------------
        */
    

    2. java.time.LocalDate类

    import java.time.LocalDate;
    
    public class TestLocalDate{
        public static void main(String[] args){
            //LocalDate date1 = new LocalDate();   不正确
            //此时用静态工厂方法代表调用的构造器
    
            LocalDate date = LocalDate.now();       
            System.out.println("The LocalDate : " + date);
            
            LocalDate date2 = LocalDate.of(2018,7,16);
            System.out.println("The LocalDate : " + date2);
            
            //LocalDate类中的方法学习
            int dayOfYear = date.getDayOfYear();   
            int dayOfMonth = date.getDayOfMonth();  
            int month = date.getMonthValue();
            int year = date.getYear();
            
            System.out.println("getDayOfYear() : " + dayOfYear 
                    + "\ngetDayOfMonth() : " + dayOfMonth 
                    + "\ngetMonthValue() : " + month 
                    + "\ngetYear() : " + year);             
        }
    }
    
    /*
        在JDK1.8中输出结果为:
        ------------------------------------
        The LocalDate : 2018-07-16
        The LocalDate : 2018-07-16
        getDayOfYear() : 197                            //按照阴历计算
        getDayOfMonth() : 16
        getMonthValue() : 7
        getYear() : 2018
        ------------------------------------
    */
    

    3. 对象和类的理解

    1. Employee类

      • data field:

        • name,salary,hireDay
      • method:

        • getName();
        • getSalary();
        • gethireDay();
      • class Employee

          import java.time.LocalDate;
          
          class Employee{
              
              //data field
              private String name;
              private double salary;
              private LocalDate hireDay;
              
              //constructor
              public Employee(String name,double salary,int year,int month,int day){
                  this.name = name;
                  this.salary = salary;
                  this.hireDay = LocalDate.of(year,month,day);
              }
              
              //method
              public String getName(){
                  return name;    
              }
              
              public double getSalary(){
                  return salary;  
              }
              
              public LocalDate gethireDay(){
                  return hireDay;
              }
              
              public void raiseSalary(double byPercent){
                  salary += salary * byPercent/100;
              }
          }
        
    2. EmployeeTest类

       public class EmployeeTest{
           public static void main(String[] args){
               Employee[] staff = new Employee[3];
               
               staff[0] = new Employee("zhangsan",100,2018,7,9);
               staff[1] = new Employee("lisi",200,2018,7,16);
               staff[2] = new Employee("hahaha",300,2018,7,23);
               
               System.out.println("=====================所有员工信息======================");
               
               //raise everyone's salary by 5%
               for(Employee e : staff){
                   e.raiseSalary(5);
               }
               
               //输出所有员工信息
               for(Employee e : staff){
                   System.out.println("name : " + e.getName()
                   + "  salary : " + e.getSalary()
                   + "  hiredate : " + e.gethireDay()
                   );      
               }
           }   
       }
       /*
           在JDK1.8中输出结果为:
           ---------------------------------------------------------
           =====================所有员工信息======================
           name : zhangsan  salary : 105.0  hiredate : 2018-07-09
           name : lisi  salary : 210.0  hiredate : 2018-07-16
           name : hahaha  salary : 315.0  hiredate : 2018-07-23
           ---------------------------------------------------------
       */
      

    4. 关键字的学习

    1. final

      • final修饰实例域(data field)时
        • 确保在每一个构造器执行后,这个域的值被设置
        • 在后面操作中,不能够再对它进行修改
        • 例如在Employee类中name域声明为final
        •   class Employee{
                private final String name;
                
                ....
            }   
          
      • final关键字只是表示对象的引用不会再指示其他对象
    2. static

      • static修饰实例域时,每个类中只有一个这样的域
        • 给每一个雇员一个标识码

            class Employee{
                private static nextID;
                private int id;
            }
          
        • 此时这个类的所有实例共享nextID域,静态域属于类,不属于任何独立的对象

    * static修饰静态常量时,例如:
    
             public class Math{
                public static final double PI = 3.141592653.....;
             }
        * 此时可通过类名直接使用PI常量:Math.PI;
        
    * static修饰方法时,表示静态方法是一种不能向对象实施操作的方法
        * 静态方法不可以访问非静态的
        * 非静态的可以访问静态的
    
    1. this

      • this指示隐士参数,也就是所构造的对象

          public Employee(String name,double salary){
              this.name  = name;
              this.salary = salary;
          }
        
        • this指的是当前对象
      • this调用另一个构造器
        public Employee(double s){
        //calls Employee(String,double)
        this("Employee #" + nextID.s);
        nextID++;
        }

    5. 工厂方法的学习

    • 使用场景

      • 在任何需要生成复杂对象的地方,可以直接new的不需要工厂模式,也就是,当使用构造器无法改变所构造的类型时。
      • 需要生成的对象叫做产品,生成对象的地方叫做工厂。
    • 例1:吃水果时需要区分不同水果类————课堂例子

      • 创建Fruit接口,定义水果eat规范

          interface Fruit{
              public void eat();
          }
        
      • 创建Apple和Orange两类,继承接口,实现抽象方法eat

          class Apple implements Fruit{
              public void eat(){
              System.out.println("吃苹果");
              }
          }
          
          class Orange implements Fruit{
              public void eat(){
                  System.out.println("吃橘子");
              }   
          }
        
      • 创建工厂,生产两产品

          class Factory{
              public static Fruit getFruit(String name){
                  if(name.equals("apple")){
                      return new Apple(); 
                  }
                  else if(name.equals("orange")){
                      return new Orange();    
                  }   
                  else{
                      return null;
                  }
              }
          }
        
      • 测试工厂类

          public class Test{
              public static void main(String[] args){
              Factory.getFruit(args[0]).eat();
              }
          }
        
          /*
              此时程序不严谨,当输入的参数不是apple和orange时抛出java.lang.NullPointerException
          */      
        
        • 此时的工厂可做到需要什么取什么,而我们不需要知道内在如何完成。

    5.1 系统学习工厂模式

    一. 简单(静态)工厂

    一个例子:

    喜欢吃水果,此时抽象一个水果类或者接口,此时这就是产品的抽象类

    abstract class Fruit{
        /*
        描述说过什么样,有多好吃    
        */
    
        public abstract void desc();
    }
    

    先尝尝苹果(具体的产品类)

    class AppleFruit extends Fruit{
        @Override           
        public void desc(){
            System.out.println("苹果好吃还便宜,嘻嘻嘻");
        }
    }
    

    再试试橘子(具体的产品类)

    class OrangeFruit extends Fruit{
        @Override           
        public void desc(){
            System.out.println("橘子好久没吃了,有点酸");
        }
    }
    

    还有我最爱吃的榴莲(具体的产品类)

    class DurianFruit extends Fruit{
        @Override           
        public void desc(){
            System.out.println("榴莲我觉得很好吃啊");
        }
    }
    

    准备工作做完了,我们来到一家“简单水果店”(简单工厂类),菜单如下:

    class SimpleFruitFactory{
        public static final int TYPE_APPLE = 1; //苹果
        public static final int TYPE_ORANGE = 2; //橘子
        public static final int TYPE_DURIAN = 3; //榴莲
    
        public static Fruit createFruit(int type){
            switch(type){
                case TYPE_APPLE:
                    return new AppleFruit();
                case TYPE_ORANGE:
                    return new OrangeFruit();
                case TYPE_DURIAN:
                    return new DurianFruit();
            }
        }
    }
    

    简单的水果店就提供三种水果(产品),你说你要啥,他就给你啥。这里我买了一个榴莲:

    /*
        简单工厂模式
    */
    
    public class Test{  
        public static void main(String[] args){
            Fruit fruit = SimpleFruitFactory.createFruit(SimpleFruitFactory.TYPE_DURIAN);
            fruit.desc();
        }   
    }
    

    在JDK1.8中输出结果为:

        ------------------
        榴莲我觉得很好吃啊
        ------------------- 
    
    简单(静态)工厂特点
    • 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。

    • create()方法通常是静态的,所以也称之为静态工厂。

    简单(静态)工厂缺点
    • 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)

    • 不同的产品需要不同额外参数的时候 不支持,因为switch的原因

    二. 多方法工厂(常用)

    • 多方法的工厂模式为不同产品,提供不同的生产方法,使用时 需要哪种产品就调用该种产品的方法,使用方便、容错率高。

    • 水果工厂类

        class MulWayFruitFactory{
        
            /*
                吃苹果
            */
            public static Fruit createApple(){
                return new AppleFruit();
            }
            
            /*
                吃橘子
            */
            public static Fruit createOrange(){
                return new OrangeFruit();
            }
            
            /*
                吃榴莲
            */
            public static Fruit createDurian(){
                return new DurianFruit();
            }
        }
            
        //测试
        public class Test{
            
            public static void main(String[] args){
                Fruit fruit = MulWayFruitFactory.createApple();
                fruit.desc();
            }   
        }
      
      • 多方法工厂一个好处在于,只需要创建产品类以及在工厂类中添加static方法即可

    三. 普通工厂(常用)

    • 普通工厂就是把简单工厂中具体的工厂类,划分成两层:抽象工厂层+具体的工厂子类层。(一般->特殊)

    水果生产工厂(抽象工厂类),作用就是生产水果

    abstract class FruitFactory{
        public abstract Fruit create();
    }
    

    苹果工厂(具体工厂类)

    class AppleFactory extends FruitFactory{
        @Override
        public Fruit create(){
            return new AppleFruit();
        }
    }
    

    橘子工厂(具体工厂类)
    class OrangeFactory extends FruitFactory{
    @Override
    public Fruit create(){
    return new OrangeFruit();
    }
    }
    榴莲工厂(具体工厂类)
    class DurianFactory extends FruitFactory{
    @Override
    public Fruit create(){
    return new DurianFruit();
    }
    }
    测试:

    public class Test{
        public static void  main(String[] args){
            FruitFactory factory = new OrangeFactory();
            
            factory.create().desc();
        }
    }
    
    /*
        在JDK1.8中输出结果为:
        ----------------------
        橘子好久没吃了,有点酸
        ----------------------
    */
    

    普通工厂和简单工厂区别:

    • 普通工厂模式特点:不仅仅做出来的产品要抽象, 工厂也应该需要抽象。
    • 工厂方法使一个产品类的实例化延迟到其具体工厂子类.
    • 工厂方法的好处就是更拥抱变化。当需求变化,只需要增删相应的类,不需要修改已有的类。
    • 而简单工厂需要修改工厂类的create()方法,多方法静态工厂模式需要增加一个静态方法。
    • 引入抽象工厂层后,每次新增一个具体产品类,也要同时新增一个具体工厂类

    此工厂方法的理解转载自https://blog.csdn.net/zxt0601/article/details/52798423#commentBox

    6. 块优先级的学习

    • Employee类

        import java.time.LocalDate;
        import java.util.Random;
      
        class Employee{
            private static int nextID;
            
            //data field
            private int id;
            private String name = "";
            private double salary;
            
            //static块
            static{
                Random random = new Random();
                nextID = random.nextInt(10000);         
            }
            
            //普通块
            {
                id =nextID;
                nextID++;   
            }
            
            //三个重载方法
            public Employee(String name,double salary){
                this.name = name;
                this.salary = salary;   
            }
            
            public Employee(double salary){
                this("hahaha",salary);  
            }
            
            public Employee(){
                    
            }
            
            public String getName(){
                return name;
            }
            
            public double getSalary(){
                return salary;
            }
            
            public int getId(){
                return id;  
            }   
        }
      
    • EmployeeTest类

        public class EmployeeTest{
            public static void main(String[] args){
                Employee[] staff = new Employee[3];
                
                staff[0] = new Employee("zhangsan",100);
                staff[1] = new Employee(200);
                staff[2] = new Employee();
                
                //输出所有员工信息
                for(Employee e : staff){
                    System.out.println("name : " + e.getName()
                    + "  salary : " + e.getSalary()
                    + "  id : " + e.getId()
                    );      
                }
            }   
        }
      
        /*
            在JDK1.8中输出结果为:
            ---------------------------------------------------------
            name : zhangsan  salary : 100.0  id : 2269
            name : hahaha  salary : 200.0  id : 2270
            name :   salary : 0.0  id : 2271
            ---------------------------------------------------------
        */
      
        /*
            此时可看出优先顺序
            static > 普通块 
        */
      

    7. 类设计技巧的学习

    1. 一定要保证数据私有

      • 绝对不能破坏封装性
      • 保持实例域的私有性
    2. 一定要对数据初始化

      • 不要依赖系统默认值
      • 显式的初始化所有的数据
      • 初始化方式
        • 提供默认值
        • 构造其中设置默认值
    3. 不要在类中使用过多的基本类型

      • 用其他的类代替多个相关的基本类型的使用
    4. 不是所有的域都需要独立的域访问器和域更改器

    5. 将职责过多的类进行分解

      • 也不要分解到过多
    6. 类名和方法名要能够体现他们的职责

    7. 优先使用不可变的类

    相关文章

      网友评论

          本文标题:7-16笔记-面向对象之对象和类

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