Java面向对象之类与对象(一)

1.面向对象简介

     Java语言是一门面向对象的语言,Java语言最大的特点在于面向对象的编程设计,并且面向对象的编程设计也在由于Java自身的发展而不断发展,同时最初不支持面向对象的编程也都开始转向了面向对象。但是依然有许多的开发者认为面向过程编程会比较好。

  最早并且一直到现在流行的编程语言C、C++、Java。其中C语言已经变成了面向过程开发的代表,C++、Java都是面向对象的变成语言。

     所谓的面向过程指的是面对于一个问题的解决方案,更多的情况下不会做出重用的设计的思考,而面向对象主要的设计形式为模块化设计,并且可以进行重用配置。在整个的面向对象的设计里面更多情况下考虑的是标准,在使用的时候根据标准进行拼装,而对于面向对象设计有三个主要的特征:

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

        在进行面向对象的开发中一般有三个步骤:

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

2.类与对象简介

面向对象是一个非常庞大的话题,但是任何庞大的话题都有其核心的组成:类与对象

类是对某一类事物的共性的抽象概念,而对象描述的是一个具体的产物

例如:现在我和某一位先生可以立刻区分出我还有别人。我和其他的人都一样,都是一个个具体可以使用的个体产物,

但是这些个体都有一些共性的标志人,中国人,美国人

人和人是不同的名字,肤色,性别,身高

所谓的人和人之间不同依靠的是我们各自的属性每一个属性的集合就构成了一个对象

但是所有的属性应该是群体定 义

群体的定义就形成了一个

          

类是一个模板,而对象才是可以使用的实例先有类再有对象
在类之中一般都会有两个组成:
成员属性(Field):         有些时候为了简化称其为属性:
什么是属性:              一个人的年龄、姓名都是不同的,所以这些对于整体来讲就成为属性
操作方法(Method):     定义对象具有处理行为;
什么是方法:             这个人可以唱歌、跳舞、游泳、运动;

 3.类与对象的基本使用

在Java之中类是一个独立的结构体,所以需要使用class来进行定义,而在类中主要由属性方法组成,

那么在类中的属性就是一个个具体的变量方法就是可以重复执行的代码

范例:定义一个类

    public class Person{ //定义一个类
        String name ; //人员的姓名
        int age ;    //人员的年龄
//定义一个方法 public void tell(){ System.out.println("姓名:" + this.name + "、年龄:" + age); } }

 

在这个类之中定义有两个属性(name、age)和一个方法(tell()) 于是说现在有了类之后
如果想使用类,必须通过对象来完成,而如果要产生对象,则必须使用以下语法格式来完成
声明并实例化对象类名称  对象名称 = new   类名称();

分步骤完成:

声明对象类名称   对象名称 = null;

实例化对象对象名称 = new 类名称();

当获取了实例化对象之后,那么就需要通过对象对类中的属性和方法调用
此时有两种调用方式:
调用类中的属性:实例化对象.成员属性;
调用类中的方法:实例化对象.方法名称();
当你不对属性值进行设置时候,则该属性值为对应数据类型的默认值
String 默认值为:null
int 默认值为:0


范例:使用对象操作类

        public class JavaDemo{
            public static void main(String args[]){
                Person per = new Person(); //声明并实例化对象
                per.name = "张三"; //设置属性姓名值
                per.age = 18 ;     //设置属性年龄值
                per.tel();        //进行方法的调用
            }
        }        

执行结果:

如果不设置属性值执行结果:

4.对象内存分析 

对象实例化操作初步分析
Java之中属于引用数据类型,引用数据类型最大的困难之处在于
要进行内存的管理,同时在进行操作的时候也会发生有内存关系变化

所以本次针对与之前的程序的内存关系进行一些简单的分析。

范例:以下面的程序为主进行分析

     

  public class JavaDemo{
            public static void main(String args[]){
                Person per = new Person(); //声明并实例化对象
                per.name = "张三"; //设置属性姓名值
                per.age = 18 ;     //设置属性年龄值
                per.tel();        //进行方法的调用
            }
        }  

如果要进行内存分析,那么首先要给出两块最为常用的内存空间:

      •   堆内存: 保存的是对象具体信息
      •   栈内存: 保存的是一块堆内存地址,即:通过地址找到堆内存,而后找到对象内容,

但是为了分析简化起见简单的理解为对象的名称保存在了栈内存之中

清楚了以前关系之后,那么下面针对之前的程序进行分析

将属性的值设置后运行程序结果为:

在之前的内存分析操作中可以发现实例化对象有两种方式:

      1.   一种是之前使用的声明并实例化对象

      2 .  一种是分布完成实例化对象的操作;

下面对于分布的内存操作进行分析:

范例:定义程序代码

      

        public class JavaDemo{
            public static void main(String args[]){
                Person per = null; //声明对象
                per = new Person();      //实例化对象
                per.name = "张三"; //设置属性姓名值
                per.age = 18 ;     //设置属性年龄值
                per.tel();        //进行方法的调用
            }
        }          

结果还是一样不变:

需要注意的是所有的对象必须在对象实例化完成之后才可以执行

范例:错误示范

    

     public class JavaDemo{
            public static void main(String args[]){
                Person per = null; //声明对象
                //per = new Person();//将创建实例化的代码注释掉 //实例化对象
                per.name = "张三"; //设置属性姓名值
                per.age = 18 ;     //设置属性年龄值
                per.tel();        //进行方法的调用
            }
        }       

代码中只声明了对象而未实例化对象,所以此时无法调用它的属性和方法。

程序报错:

 

此时会报一个NullPointerException(空指向异常) ,就是 (实例化对象)没有在堆内存开辟后时所产生的问题,

并且只有引用数据类型存在有此异常NullPointerException,基本数据类型存在异常,此异常伴随整个开发人生

5.对象引用分析

类本身属于引用数据类型,那么就牵扯到内存的引用传递

所谓的引用传递的本质同一块堆内存空间可以被不同栈内存指向,也可以更换指向

范例:定义一个引用传递的分析程序:

 

 public class JavaDemo{
        public static void main(String args[]){
            Person per1 = new Person();  //声明并实例化对象
            per.name = "张三";
            per.age = 18 ;        
            Person per2 = per1 ; //引用传递
            Person.age = 80 ;
            per.tell() ;        //进行方法的调用
        }
 }

 

运行结果:

6.引用传递与垃圾产生分析

范例:定义一个要分析的程序

 

 public class JavaDemo{
        public static void main(String args[]){
            Person per1 = new Person();  //声明并实例化对象
            Person per2 = new Person();  //声明并实例化对象
            per1.name = "张三";
            per1.age = 18 ;   
            per2.name = "李四";
            per2.age = 19 ;         
            Person per2 = per1 ; //引用传递
            Person.age = 80 ;
            per1.tell() ;        //进行方法的调用
        }
 }    

 

此时已经明确的发生了引用传递,并且也成功的完成了引用传递的处理操作,

下面来观察下内存分配处理流程

 

所谓的垃圾空间指的就是没有任何栈内存所指向的堆内存空间,所有的垃圾将被GC(Garbage Collector、垃圾收集器) 不定期进行回收并且释放无用内存空间,但是垃圾过多,一定将影响到GC的处理性能,从而降低整体的程序性能,那么在实际的开发之中,对于垃圾的产生应该越少越好。

一个栈内存只能够保存有一个堆内存的地址数据,如果发生更改,则之前的地址数据将从此栈内存中彻底消失。

 

 

 7.构造方法与匿名对象

现在的程序在使用类的时候一般都按照了如下的步骤进行:

  • 声明并实例化对象,这个时候实例化对象中的属性并没有任何的数据存在,都是其对应数据类型的默认值;
  • 需要通过一系列的 setter 方法为类的属性设置内容;

等于现在想要真正获得一个可以正常使用的实例化对象,必须经过两个步骤才可以调用

 范例传统调用

 public class JavaDemo{
        public static void main(String args[]){
            Person per = new Person();  //声明并实例化对象
            per.setName("张三");
       per.setAge(18); per1.tell() ;
//进行方法的调用 } }

通过以上案例可以发现,假设我们有8个属性那么我们需要写8个setter方法来进行设置值,这样调用实在是太啰嗦了,

为了解决这个问题Java专门提供了构造方法

可以通过构造方法实现实例化对象中的属性初始化处理。

       只有在关键字 new 的时候才会使用构造方法

       在Java程序里面构造方法的定义要求如下:

 

  •   构造方法名称必须与类名称保持一致
  •        构造方法不允许设置任何的返回值类型,即:没有返回值定义
  •        构造方法是在使用关键字 new  实例化对象的时候自动调用的

范例:定义构造方法

   class Person{ //定义一个类
        String name ; //人员的姓名
        int age ;    //人员的年龄
     //方法名称与类名称相同,并且无返回值定义
     public Person(String naem,int age){ //定义有参构造
this.name = name; //为类中的属性赋值(初始化)
  this.age = age ; //为类中的属性赋值(初始化)
}
//定义一个方法 public void tell(){ System.out.println("姓名:" + this.name + "、年龄:" + age); }
       }

public class
JavaDemo{

public static void main(String args[]){
Person per = new Person("张三",18); //声明并实例化对象
per1.tell() ; //进行方法的调用
        }
 }    
 

运行结果:

下面针对于当前的对象实例化格式与之前的对象实例化格式做一个比较:

  •     之前的对象实例化格式:①Person ②per = ③new ④Person();
  •     当前的对象实例化格式:①Person ②per = ③new ④Person("张三",18);

      ①Person :类型决定了你可以调用的方法;

                      ②per       :实例化对象的名称,所有的操作通过对象来进行访问;

                      ③new      :开辟一块新的堆内存空间;

                      ④Person("张三",18) :调用有参构造、"④Person()"调用无参构造

在Java程序里面考虑到程序结构的完整性,所有的都会提供有构造方法,也就是说如果现在你的类中没有定义任何的构造方法

那么Java一定会默认提供一个无参的,什么都不做的构造方法,这个构造方法是在程序编译的时候自动创建的

如果你现在已经在类中明确的定义有一个构造方法的时候

那么这个默认的构造方法将不会被自动创建

结论:一个类至少存在一个构造方法,永恒存在

疑问:为什么构造方法上不允许设置返回值类型?

既然构造方法是一个方法,那么为什么不让它定义返回值类型呢?

既然构造方法不会返回数据,为什么不使用 void 来定义呢?

分析:程序编译器是根据代码结构来进行编译处理的,执行的时候也是根据代码结构来处理的

如果在构造方法上使用了void ,那么次结构就与普通方法的结构完全相同的了,这样编译器就会识别成普通方法、

普通方法构造方法最大的区别构造方法是在类对象实例化的时候调用的而普通方法是在类对象实例化产生之后调用的

既然构造方法本身是一个方法,那么方法就具有重载特点,而构造方法重载的时候只需要考虑参数的类型及个数即可

 

 

 public class Person{
    private String name;
    private int age ;
    public Person(){}//无参构造
    public Person(String name){//带一个参数有参构造
            this.name = name;
    }
    public Person(String name,int age){//带两个参数有参构造
            this.name = name;
            this.age = age;
    }
        
 }

 

posted @ 2018-09-20 20:00  wangf98  阅读(3348)  评论(0编辑  收藏  举报