首页 > 学院 > 开发设计 > 正文

类和对象及方法的的初步认识

2019-11-08 01:59:25
字体:
来源:转载
供稿:网友

类和对象的初步认识

定义类和对象

java程序基本的单位是类(class)。

在面向对象中,类也是它的重要内容。

Java数据类型:基本数据类型;引用数据类型。

引用数据类型:String、Scanner……,他们都是预先写好的类,把他们当做数据类型来使用。一定意义上来说,类也可以称为引用类型。

String str =new String();

定义类的格式:[修饰符] class 类名{         //定义属性         //定义方法         //定义构造器方法}

练习:定义一个类Person,将这个类作为引用数据类型,再定义测试类,测试Person引用数据类型。

class Test{public static void main(String[] args){Person p = new Person();//设置属性p.name = "zhangsan";p.age = 18;//调用方法p.getInfo();}}class  Person{//定义属性String name; int age; //定义方法void getInfo(){System.out.PRintln("name"+name+"/n age"+age); }}

 

什么是对象?

         对象,是一个具体存在的事物,他具有属性和行为(方法)。如:人,电脑,食物。

类和对象的关系:

类:说明书,图纸;

如果对象是建筑的话,类就是建筑的图纸;

对象是食物的话,类就是菜谱;

类就是用来描述对象的,描述对象具有什么属性,什么行为,类定义了对象。

类是:抽象的,对象就是具体的。

类与对象存在的关系:

         对象是通过类创造的,那么类是优先于对象存在而存在。换句话说,类存在,对象不一定存在,但是对象存在了,类一定存在。

         注意:“对象存在,类不存在”是不可能的,如果图纸都没有,那么怎么去盖房?

静态修饰符 static:

static只能修饰类的成员。

static 修饰变量:

static 类型 变量名;

static 返回值 方法名(){}

Static修饰的成员:是静态的,直接属于类,而不属于类创造出来的对象,随着类的创建而创建,随着类的消失而消失。

当类存在的时候,被static修饰的成员就一起存在了。

没有用static修饰的成员,当类存在的时候,这些成员并不存在。

这个时候,使用类名.静态成员是OK的,但是使用类名.非静态成员,是错误的,因为非静态成员并不是与类一起产生,那么使用一个存在的东西去访问一个不存在的东西,肯定是不行的!

怎么访问没有被static修饰的非静态成员?

可以通过new关键字创建该类对象,使用对象.非静态成员方式调用,没有被static修饰的非静态修饰的成员只属于创造出来的对象本身。

 

存在的顺序:类、静态成员优先于对象、非静态成员存在。

提示:按照存在顺序可以得出,静态成员只能调用、访问静态成员,不能访问非静态成员;非静态成员可以访问静态成员。

class%20Test{%20%20%20%20publicstatic%20void%20main(String[]%20args){%20%20%20%20%20%20%20%20//静态成员是与对象一起存在,所以可以通过类名.静态成员方式调用%20%20%20%20%20%20%20%20System.out.println(Animal.zhonglei);%20%20%20%20%20%20%20%20//cat是非静态成员,Aniaml调用这个时候还不存在的成员,会报错%20%20%20%20%20%20%20%20System.out.println(Animal.cat);%20%20%20%20%20%20%20%20Animalani%20=%20new%20Animal();%20%20//创建对象后,可以使用对象.非静态成员方式调用,也就是说,非静态成员属于对象%20%20%20%20%20%20%20%20System.out.println(ani.cat);%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//使用对象.静态成员%20不报错,因为静态成员优先于对象而存在。%20%20%20%20%20%20%20%20System.out.println(ani.zhonglei);%20%20%20%20%20%20%20}}class%20Animal{%20%20%20%20staticString%20zhonglei%20=%20"动物";%20%20%20%20Stringcat="猫";}%20class%20%20Person{%20%20%20%20String%20a%20="aa";%20%20%20%20staticString%20b%20="bb";%20%20%20%20//验证静态成员调用非静态成员%20%20%20%20//静态方法,调用非静态成员是错误的!%20%20%20%20/*staticvoid%20m1(){%20%20%20%20%20%20%20%20a%20="abc";%20%20%20%20}*/
%20%20%20%20//验证非静态成员调用静态成员.%20%20%20%20void%20m2(){%20%20%20%20%20%20%20%20b%20="abc";%20%20%20%20}}

直接类名调用成员和创建对象调用成员的区别:

类名调用成员,只能调用静态成员,不能调用非静态成员。

对象调用成员,既可以调用非静态成员,也可以调用静态成员,也就是说,非静态成员只属于它们的对象。

 

对象与对象之间的关系与区别:

使用同一个类Dog创建出来的对象,是两个具体存在的事物,不是同一个,他们虽然类型和属性相同,但是互不影响,他们都是独立存在的个体。

N个对象与静态成员之间的关系:

静态成员直接属于类,是唯一的。对象也可以直接访问静态成员,所以说,N多个该类的实例对象访问的静态成员其实是同一个,换句话说,静态成员被N多个实例对象共享。

 

 

 

 

特殊的成员:构造器方法

构造器方法:是用来构造对象的,当我们使用new关键字创建对象的时候,这个创建过程是一个行为、动作。其实他也是一个方法,只不过我们以前是没有注意过这个方法。

定义格式:

public%20类名([参数类型%20参数名]){

   %20//代码

}%20

使用方式:

构造器方法,当我们使用new关键字创建对象的时候调用。

new%20Animal();//这个时候,实际上是调用了对象的构造器方法。如果我们在定义对象的时候,没有写构造器方法,就会隐式的存在一个无参的构造器方法。class%20Animal{%20%20%20%20staticString%20zhonglei%20=%20"动物";%20%20%20%20Stringcat;%20%20%20%20Stringage;}%20

当我们定义了构造器方法,那么这个无参构造器就消失了。

class%20Animal{%20%20%20%20%20publicAnimal(String%20a){%20%20%20%20%20%20%20%20age%20=a;%20%20%20%20}%20%20%20%20staticString%20zhonglei%20=%20"动物";%20%20%20%20Stringcat;%20%20%20%20Stringage;}%20

当我们定义了构造器,并且指定了构造器需要的传参参数,之前隐式的空构造器方法就会消失。

对象创建后,对象的成员的默认值:

Int:0

Byte:0

Long :0

Short :0

Double:0.0

Float:0.0

Char:’’//编码表里面编码为0的那个字符

Boolean:false

 

引用数据类型:null

对象的引用和生命周期:

对象的创建:

使用new关键字创建对象,在堆空间中,开辟一块区域用来存放这个对象的数据,然后将这个对象的门牌号(地址值)赋值给栈空间中该类型变量。

引用:栈空间中的变量指向堆空间中的对象。

用手机号绑定QQ账号,使用手机号登陆QQ和使用QQ号登陆QQ,登陆的是同一个账户。那么使用手机号登陆QQ后,发了一条朋友圈,再使用QQ账号登陆,那条朋友圈信息还在。

栈空间中的变量可以有N个同时指向堆空间中的同一个对象。那么使用这几个引用变量去访问数据,其实访问的是同一个数据。

   %20

 

%20%20%20%20%20%20%20%20//dog1存储的是指向dog对象的地址Dogdog1%20=%20new%20Dog();%20%20%20%20%20%20%20%20dog1.name=%20"哈士奇";%20%20%20%20%20%20%20%20dog1.age=%203;%20%20%20%20%20%20%20%20Dogdog1_1%20=%20dog1;%20%20%20%20%20%20%20%20System.out.println(dog1_1.name);%20%20%20%20%20%20%20%20dog1_1.name=%20"泰迪";%20%20%20%20%20%20%20%20System.out.println(dog1.name);

分析:定义dog1指向一个对象,将他存储的地址赋值给dog1_1,那么使用dog1_1和dog1去访问、操作的其实是同一个对象。

对象的消失:

        %20当没有引用(变量)指向对象时候,对象无法被访问和操作了。那么在堆空间中的对象就是垃圾。

        %20Java提供一个垃圾回收机制,GC,通过该线程不定时的回收垃圾(没有引用指向的对象)。

      

  //对象没用了,那么怎么回收对象所占用的内存空间        //将引用指向对象的连接中断就可以了。        dog1 =null;        //System.out.println(dog1.name);空指针异常        dog1_1=null;        /*这个时候,已经没有任何引用指向之前定义的对象        那么之前的那个对象就是垃圾了,java的GC会不定时        清理垃圾        */

构造器:

用来创建对象,使用new关键字创建对象,实际上就是调用该对象的构造器方法。

构造器方法与普通方法区别:

1、  没有返回值,不能使用return

2、  调用方式是使用new关键字调用,而方法是通过 类名.方法名调用。

3、如果没有定义构造器方法,那么java会有一个隐藏的无参构造器,如果定义了构造器方法,那么该隐藏的无参构造器就消失。

构造器除了用来创建对象,还可以做一些对象初始化动作。

class Test{    publicstatic void main(String[] args){        Dogdog1 = new Dog();        System.out.println(dog1.name);    }   }class Dog{    //在创建Dog类型对象时,对象的属性就有初始值。    publicDog(){        name ="哈士奇";    }    staticString aixinjiayuan = "爱心家园";    Stringname;}还可以传参给构造器,用来初始化数据。class Test{    publicstatic void main(String[] args){        Dogdog1 = new Dog("金毛");        System.out.println(dog1.name);        Dogdog2 = new Dog("哈士奇");        System.out.println(dog2.name);    }   }class Dog{    //在创建Dog类型对象时,对象的属性就有初始值。    publicDog(String str){        name =str;    }    staticString aixinjiayuan = "爱心家园";    Stringname;}

this 关键字:

代表所在的类中创建出来的对象本身。

class Dog{    //在创建Dog类型对象时,对象的属性就有初始值。    //遇到局部变量与外部变量重名,可以使用this找到外部变量。    //this代表当前创建的对象本身。    publicDog(String name){        this.name= name;    }    staticString aixinjiayuan = "爱心家园";    Stringname;}

方法的定义:具有一定功能的代码块,有返回值,也可以传参。

定义格式:

[修饰符] 返回值方法名([参数类型参数名称]){

         //0到多行代码块

}

方法的重载:

         在一个类里面,可以定义n多个同名方法,只需要参数列表不同即可。

重载只与形参列表有关,与返回值、修饰符无任何关系。

 

    publicstatic int add(int a , int b){        returna+b ;    }    publicstatic int add(int a , int b, int c){        returna+b+c ;    }    publicstatic int add(int a , int b, int c,int d){        returna+b+c+d ;    }构造器是特殊的方法,那么构造器也可以重载:    publicDog(String name){        this.name= name;    }    publicDog(String name ,int age){        this.name= name;        this.age= age;    }    staticString aixinjiayuan = "爱心家园";    Stringname;    int age;

参数列表的可变长参数:

当我们遇到需要传递同一种参数类型的数据,但是参数个数较多,这个时候如果依次重载不同参数列表的方法,就显得代码臃肿。

如:遇到如下情况,就需要重载4个add方法。

result=AddMethod.add(1,2);         System.out.println(result);        result=AddMethod.add(1,2,3);         System.out.println(result);        result=AddMethod.add(1,2,3,4);         System.out.println(result);        result=AddMethod.add(1,2,3,4,5); 

解决这个问题,可以使用可变参数。

作用:接收同一种数据类型的数据,但是接收的参数个数是可以变化的。

接收过来以后,java自动将接收的数据封装到数组里面,在方法的代码块中,这个参数就是一个该类型的数组。我们将它当成普通数组使用即可。

 

问题:数组是一个不可改变长度的容器,为什么在使用的时候,可以传递不同长度的数据?

这里的可变参数数组的定义,是根据传递过来的参数来定义。

定义格式:

[修饰符] 返回值类型方法名(参数类型…参数名){

         //参数名就是一个该参数类型的数组。

}

 

注意:可变参数,放置的位置只能是在方法参数列表的最后一个参数的位置。并且,一个方法参数列表中只能有一个可变参数。

    publicstatic int add(String str, int ...arr){         intresult =0;        for(inti = 0;i < arr.length ; i++){            result+=arr[i];        }        returnresult;    }

特殊的方法调用:递归

递归:自己调用自己。方法内部代码调用方法本身。

 

class%20Test2{static%20int%20method(int%20i){%20%20%20%20if(i%20==1){%20%20%20%20%20%20%20%20returni%20;%20%20%20%20}%20%20%20%20int%20result=%20method(i%20-%201);%20%20%20%20returnresult;}%20public%20static%20void%20main(String[]%20args){%20%20%20%20int%20%20result%20=%20method(5);%20%20%20%20System.out.println(result);}}

案例:阶乘

阶乘:5的阶乘是%201*2*3*4*5   %206的阶乘是1*2*3*4*5*6%20从1到它本身的整数相乘。

使用for循环求阶乘:

使用递归算法求阶乘:

class JieCheng{public static void main(String[] args){int result = jiecheng(3);System.out.println(result);}public static int jiecheng(int num){    if(num ==1){        returnnum;    }     num = num * jiecheng(num -1) ;    return num;    }}

成员变量和局部变量:

成员变量:在成员位置,属于对象或者是类。随着类或对象的创建而创建,消失而消失。

局部变量:定义在方法中,随着方法的创建而创建,随着方法的消失而消失。

    //成员变量    Stringchengyuan;    //成员方法    publicvoid method(){    //局部变量    Stringjubu;    } 

 

 

 

 

 

 

 

 

 

形参:定义在方法参数列表中,表示一个参数的类型和参数名。

实参:方法执行时候,传递进来的实际参数(值)。

 

变量在内存中的生命周期:

类变量:与类同时创建,与类同时消失。

实例变量:创建对象时,创建实例变量,对象被回收,属于该对象的实例变量消失。

局部变量:方法被调用,局部变量被创建,方法执行完成,局部变量被回收。

代码块

 

 

 

 

 

 

 

 

 

代码块:执行一段代码,没有名称,没有返回值,没有参数,不能被调用。

静态代码块:类存在了(类加载到内存当中),执行静态代码块中的代码,并且只会执行一次。

class Test{    //类加载到内存中就执行该代码块    static {        System.out.println("静态代码块执行了");    }    publicstatic void main(String[] args){     }   } 第二种情况:class Test{    publicstatic void main(String[] args){    Dog dog1 =new Dog();    }   }class Dog{    //类加载到内存中就执行该代码块    static {        System.out.println("静态代码块执行了");    }}  构造代码块:对象创建(new Dog()),执行一遍构造代码块,并且只会执行一次。class Test{    publicstatic void main(String[] args){    Dog dog1 =new Dog();    Dog dog2 =new Dog();    }   }class Dog{    //对象一旦创建就执行该代码块    {        System.out.println("普通代码块执行了");    }}  

代码块的作用:就是初始化对象、初始化类时候做一个初始化动作,如:赋值操作。

 

类、对象产生的顺序及在内存中的存储:

类加载到内存,通过类名调用静态方法,如:类名.静态方法;通过类创建对象,new 对象()。

对象加载到内存,就是new关键字创建后加载到内存。

 

 

 

 

静态成员、静态代码块、实例变量、构造代码块、构造方法

以new对象为例,说明类和对象中数据以及代码块执行的顺序:

class Test{    publicstatic void main(String[] args){    Dog dog1 =new Dog();    //当我执行new Dog()会发生了什么事情?    /*        1、加载类到静态区域        2、先创建静态成员        3、执行静态代码块        4、创建实例变量        5、构造代码块        6、构造方法    */     }}class Dog{    //如果不给静态成员初始化值,会有默认初始值    staticString aixinjiayuan = "abc";    Stringname = "泰迪";    staticvoid jingtai(){        intnum = 0;    }    voidshili(){        Stringstr = "";    }    //静态代码块    static {        System.out.println(aixinjiayuan);        System.out.println("普通代码块执行了");    }    //对象一旦创建就执行该代码块    {        System.out.println(name);        System.out.println("普通代码块执行了");    }    publicDog(){        System.out.println("构造方法执行了");    }}   

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表