第五章 面向对象

  面向对象的三大特征:封装,继承和多态。Java提供了private,protected和public三个访问控制修饰符来实现良好的封装,提供了extends关键字来让子类继承父类,子类继承父类将可以继承到父类的属性和方法,如果访问控制允许,子类实例可以直接调用父类里定义的方法。继承是实现类复用的重要手段。
  构造器用于对类实例进行初始化操作,构造器支持重载,如果多个重载的构造器里包含了相同的初始化代码,则可以把这些初始化代码放置在普通初始化块里完成 ,初始化块总在构造执行前被调用。
   Java语言里定义类的简单语法如下:
    [修饰符] class 类名
     {
       零个到多个构造器定义..
       零个到多个属性...
       零个到多个方法...   
      }
   定义属性的语法格式如下:
     [修饰符]  属性类型  属性名 [=默认值]
    属性语法格式的详细说明如下:
        *修饰符:修饰符可以省略,也可以是public,protected,private,static,final,其中public,protected,private三个最多只能出现其中之一,可以与static,final组合起来修饰属性。
        *属性类型:属性类型可以是Java语言允许的任何数据类型,包括基本类型和现在介绍的引用类型。
        *属性名:属性名则只要是一个合法的标识符即可,但这只是从语法角度来说的;如果从程序可读性角度来看,属性名应该由一个或多个有意义的单词连缀而成,第一个单词首字母小写,后面的每个单词首字母大写,其他字母全部小写,单词与单词之间不需要使用任何分隔符。
        *默认值:定义属性还可以定义一个可选的默认值。
       
    定义方法的语法格式如下:
          [修饰符] 方法返回值类型 方法名(形参列表)
          {
              //由零条到多条可执行性语句组成的方法体
             }
    方法语法格式的详细说明如下:
        * 修饰符:修饰符可以省略,也可以是public,protected,private,static,final,abstract,其中public,protected,private三个最多只能出现其中之一;abstract和final最多只能出现其中之一,它们可以与static组合起来修饰方法。
        *方法返回值类型:返回值类型可以是Java语言允许的任何数据类型,包括基本类型和引用类型;如果声明了方法返回值类型,则方法体内必须有一个有效的return语句,该语句返回一个变量或一个表达式,这个变量或者表达式的类型必须与此处声明的类型匹配。除此之外,如果一个方法没有返回值,则必须使用void来声明没有返回值。
        *方法名:方法名命名规则  与属性命名规则基本相同,但通常建议方法名以英文中的动词开头。
        *形参列表:形参列表用于定义该方法接受的参数,形参列表由零组到多组“参数类型 形参名”组合而成,多组参数之间以英文(,) 隔开,形参类型和形参名之间以英文空格隔开。一旦在定义方法时指定了形参列表,则调用该方法时必须传入对应他的参数值---谁调用,谁负责形参赋值。
    
   构造器的语法格式如下:
        [修饰符] 构造器名 (形参列表)
         {
            //由零条到多条可执行性语句组成的构造器执行体
          }
     构造器语法格式的详细说明如下:
         *修饰符:修饰符可以省略,也可以是public,protected,private其中之一。
         *构造器名:构造器名必须和类名相同。
         *形参列表:和定义方法形参列表的格式完全相同。
 
   对象this的引用:
      this关键字是一个对象的默认引用。this关建字总是指向调用该方法的对象。根据this出现的位置不同,this作为对象的默认引用有两种情形:
         *构造器中引用该构造器执行初始化的对象。
         *在方法中引用调用该方法的对象。
          
        public  calss  ThislnConstructor
         {
              //定义一个名为foo的属性
               public int foo;
               public ThislnConstructor()
               {
                  //在Test构造器里定义了一个foo对象
                  int   foo=6;
                   //使用this代表此构造器进行初始化的对象
                   //下面的代码将会把刚创建对象的foo属性设置为6。
                   this.foo=6;
                  }
                 public  static  void  main(String[] args){
                    //所有使用ThislnConstructor创建的对象的foo属性
                    //都将被设为6,所有下面代码将输出6.
                   System.out.println(new ThislnConstructor().foo);
                   
                 }
            } 
          
       dangthis作为对象的默认引用使用时,程序可以像访问普通引用变量一样来访问这个this引用,甚至可以把this当成普通方法的返回值。
               public  class  ReturnThis
                {
                    public int age;
                    public ReturnThis  grow()
                   {
                     g++;
                      //return  this;返回调用该方法的对象
                        return  this;
                     } 
                  public  static  void  main(String[] args){
                              ReturnThis  rt=new ReturnThis();
                                //可以连续调用同一个方法
                               rt.grow();
                                  .grow();
                               System.out.println("rt的age属性值是:"+rt.age);
                        }






                  }    


           引用类型的参数传递:
              public  class  TestRefereneTransfer
               {
                   public  static  void  swap(DataWrap  dw)
                    {
                         //下面三行到吗实现dw的a,b属性值交换。
                         //定义一个临时变量来保存dw对象的a属性的值
                           int  tem=dw.a;
                         //把dw对象的b属性值赋给a属性
                           dw.a=dw.b;    
                          //把临时变量tmp的值赋给dw对象的b属性
                          dw.b=tmp;
                            System.out.println("swap方法里,a属性的值是"+dw.a+";bde值是"+dw.b);
                         }
                           public  static void main(String[] args){
                                    Datawrap  dw=new DataWrap();
                                     dw.a=6;
                                     dw.b=9;
                                     sqap(dw);
                             System.out.println("交换结束后,a属性的值是"+dw.a+";b属性的值是"+dw.b);   
                              }
             }      


              
            形参长度可变的方法:
                     
                public  calss  Varargs{
                   //定义了形参长度可变的方法
                   public  static void test(int a,String...books){
                          //books被当成数组处理
                     for(String  tem:books){
                           System.out.println(tmp);
                         }
                          //输出整数变量a的值
                        System.out.println(a);
                     }   
                    public static void main(String[] args){
                          //调用test方法
                        test(5,"Struts2权威指南","基于J2EE的Ajax宝典");
                     }   
                 }


                  
             成员变量和局部变量
                 成员变量指的是在类范围里定义的变量(属性)
                 局部变量指的是在同一个方法内定义的变量。
                 成员变量被分为类属性和实例属性两种,定义一个属性时不使用static修饰的就是实例属性,使用static修饰的就是类属性。其中类属性从这个类的准备阶段起开始存在,直到系统完全销毁这个类,类属性的作用域与这个类的生存范围相同;而实例属性则从这个类的实例被创建开始起存在,直到系统完全销毁这个实例了,实例属性的作用域与对应实例的生存范围相同。
                 成员变量的初始化和内存中的运行机制
                       //创建第一个Person对象
                        Person  p1=new Person();
                        //创建第二个Person对象
                        Person  p2=new Person();
                        //分别为两个Person对象的name属性赋值
                         p1.name="张三";
                         p2.name="孙悟空";
                         //分别为两个Person对象的eyeNum属性赋值
                         p1.eyeNum=2;
                         p2.eyeNum=3;  
 
                  局部变量的初始化和内存中的运行机制
                     局部变量定义后,必须经过显示初始化才能使用,系统不会为局部变量执行初始化。这意味着定义局部变量后,系统并未为这个变量分配内存空间,直到等到程序为这个变量赋初始值时,系统才会局部变量分配内存,并将初始值保存到这块内存中。
                     与成员变量不同,局部变量不属于任何类或实例,因此它总是保村在该变量对应内存中;如果局部变量是一个引用类型的变量,则这个变量里存放的是地址,通过该地址引用到该变量实际引用i的对象或数组。
                     成员变量的作用域扩大到类存在范围或者对象存在范围,这种范围扩大的两大害处:
                        *增大了变量的生存时间,这将导致更大的系统开销。
                        *扩大了变量的作用域,这不利于提高程序的内聚性。


                     
                隐藏和封装
                  封装是面向对象三大特征之一(另外两个是继承和多态),他指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
                  一个类或对象实现良好的封装,可以实现一下目的:
                     *隐藏类的实现细节
                     *让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对属性的不合理访问。
                     *可进行数据检查,conger有利于保证对象信息的完整性
                     *便于修改,提高代码的可维护性
                为了实现良好的封装,需要从两个方面考虑:
                     *将对象的属性和实现细节隐藏起来,不允许外部直接访问
                     *把方法暴露出来,让方法来操作或访问这些属性。
          
              使用访问控制符
                     Java提供了三个访问控制符:private,protected和public,分别代表了三个访问控制级别,另外还有一个不加任何访问控制符的访问控制级别,提供了四个访问控制级别,访问控制级别由小到大依次:
                        private  ---  default  ---  protected  ---  public
                                  访问控制级别由小到大
                  *private访问控制级别:如果类里的一个成员(包括属性和方法)使用private访问控制符来修饰,则这个成员只能在该类的内部被访问。很显然,这个访问控制符用于修饰属性最合适,使用他来修饰属性就可以把属性隐藏在类的内部。
                  *default访问控制权限(包访问权限):如果类里的一个成员(包括属性和方法)或者一个顶级类不使用任何访问控制修饰符,我们就称它为默认访问控制,default访问控制的成员或顶级类可以被相同包下其他类访问。
                  *protected访问控制权限(子类的访问权限):如果一个成员(包括属性和方法)使用protected访问控制符修饰,那么这个成员既可以被同一个包中其他类访问,也可以被不同包中的子类访问。通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。
                  *public访问控制权限(公共访问权限):这是一个最宽松的访问控制级别,如果一个成员(包括属性和方法)或者一个顶级类使用了public修饰,这个成员或顶级类就可以被所有类访问,不管是访问类和被访问类是否处于同一个中,是否具有父子继承关系。
         
              关于访问控制符的作用,存在如下几条基本原则:
                  * 类里的绝大部分属性都应该使用private修饰,除了一些static修饰的,类似全局变量的属性,才可能考虑使用public修饰。除此之外,有些方法只是用于辅助实现该类的其他方法,这些方法成为被称为工具方法,工具方法也应该使用private修饰。
                  *如果某个类主要用做其他类的父类,该类里包含的大部分方法可能仅希望被其子类重写,而不想被外界直接调用,则应该使用protected修饰这些方法。
                  *希望暴露出来给其他类自由调用的方法应该使用public修饰。因此,类的构造器通过使用public修饰,暴露给其他类中创建该类的对象,因为顶级类通常都希望被其他类自由使用,所以大部分顶级类都使用public修饰。


                  Java源文件的大体结构如下:
                      package语句    //0个或一个,必须放在文件开始
                      import | import static语句   //0个或多个,必须放在所有类定义之前
                      classDefinition | interfaceDefinition     //0个或多个普通类或接口定义


              Java的常用包
                  *java.lang:这个包下包含java语言的核心类,如String,Math,System和Thread类等,使用这个包下的类无须使用import语句导入,系统会自动daoru这个包下所有类。
                  *java.util:这个包下包含了java大量工具类/接口和集合框架类/接口,例如Arrays和list,Set等。
                  *java.net:这个包下包含了一些java网络编程相关的类/接口。
                  *java.io:这个包下包含了一些java输入/输出编程相关的类/接口。
                  *java.text:这个包下包含了一些java格式化相关的类。
                  *java.sql:这个包下包含了一些java进行JDBC数据库编程的相关类/接口
                  *java.awt:这个包下抽象窗口工具集(Abstract Window Toolkits)的相关类/接口,这些类主要用于构建图形用户界面(GUI)程序。
                  *java.swing:这个包下包含Swing图形用户界面程序编程的相关类/接口,这些类可以用于构建平台无关的GUIchengxu。
           

                     

   继承的特点
       java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类被称为父类,有上网也被称为基类,超类。
      因为子类是一种特殊的父类,因此父类包含的范围总比子类包含的范围要大,所以可以认为父类是大类,而子类是小类。
      java里子类继承父类的语法格式如下:
      修饰符  class  SubClass  extends SuperClass
      {
       //类定义部分
      }
     java使用extends作为继承的关键字,extend关键字在英文是扩展,而不是继承,这个关键字很好的体现了子类和父类的关系:子类是对父类的扩展,子类是一种特殊的父类。从这个意义上来说,使用继承来描述子类和父类关系是错误的,用扩展更恰当。
    子类继承父类的特点
        public  class Fruit
          {
           public double weight;
           public void info()
            {
               System.out.println("我是一个水果!重"+weight+"g!");
             }        
            }


     Fruit类的子类
       public class  Apple extends  Fruit
      {
       public static void main(String[] args){
          //创建Apple的对象
         Apple  a=new Apple();
          //Apple对象本身没有weight属性
           //因为Apple的父类有weight属性,也可以访问Apple对象的属性
          a.weight=56;
           //调用Apple对象的info方法
            a.info();
        }
   }


     重写父类的方法
         鸵鸟需要重写鸟类的方法
           public  class  Bird
            {
               //Bird类的fly方法
               public void fly()
                 {
                 Sysotm.out.println("我在天空里自由自在的飞翔。。。");
                }
              }


       重写Bird的fly方法
           public  class  Ostrich  extends Bird
             {
               //重写Bird类的fly方法
                  public  void fly()
                 {
                  System.out.println("我只能在地上奔跑。。。");
               }
                 public  static  void main(string[] args)
                {
                    //创建Ostrich对象
                    Ostrich   os=new Ostrich();
                     //执行Ostrich对象的fly方法,将输出“我只能在地上奔跑。。。”
                        os.fly();
                   }




    子类中重新定义新方法
          class  BaseClass
           {
           //test方法是private访问权限,子类不可以访问该方法 
             private void  test(){...}
               }
                class  SubClass extends BaseClass
                    {
                       //此处并不是方法重写,所以可以增加static关键字
                     public static void test(){...}
         
                    }
              }
           
            父类实例的super引用
        public  void calloverridedMethod()
        {
            //在子类方法中通过super显式调用父类被覆盖的实例方法。
              super.fly();
        }
    
        调用父类构造器
       在一个构造器中调用另一个重载的构造器使用this调用来实现,在子类构造中调用父类构造器使用super调用来实现。
       class Base
       {
          public  double  size;
          public  String  name;
          public Base(double  size,String name)  
           {
              this.size=size;
              this.name=name;
            }
        }
         public  class  Sub  extends  Base
            {
               public  String  color;
               public  Sub(double size,String name,String color) 
               {
                 //通过super调用来调用父类构造器的初始化过程
                  super(size ,name); 
                  this.color=color;
                }
             public static  void  main(String[] args)
              { 
                 sub  s=new sub(5.6,"测类对象","红色");
                   //输出sub对象的三个属性
                 System.out.println(s.size+"--"+s.name+"--"+s.color);
                }
              }
    子类构造器调用父类构造器分如下几种情况:
       *子类构造器执行体的第一行使用super显式调用父类构造器,系统将根据super调用里传入的实参列表调用父类对应的构造器。
       *子类构造器执行体的第一行代码使用this显式调用本类中重载的构造器,系统将根据this调用里传入的实参列表调用本类另一个构造器。执行本类中另一个构造器时即会调用父类的构造器。
       *子类构造器执行体中既没有super调用,也没有this调用,系统将会在执行子类构造器之前,隐式调用父类无参数的构造器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统,可以是移动应用、网页服务或集成到智能农业设备。 7. **实时监测**:在实际应用,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值