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

类和对象的初步认识

定义类和对象

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




 
   //验证非静态成员调用静态成员.
    void m2(){
        b ="abc";
    }
}



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

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

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

 

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

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

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

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

 

 

 

 

特殊的成员:构造器方法

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

定义格式:

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

    //代码

}

使用方式:

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

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



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

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




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


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

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个同时指向堆空间中的同一个对象。那么使用这几个引用变量去访问数据,其实访问的是同一个数据。


   

 

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


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

对象的消失:

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

         Java提供一个垃圾回收机制,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 Test2{
static int method(int i){
    if(i ==1){
        returni ;
    }
    int result= method(i - 1);
    returnresult;
}
 
public static void main(String[] args){
    int  result = method(5);
    System.out.println(result);
}
}


案例:阶乘

阶乘:5的阶乘是 1*2*3*4*5    6的阶乘是1*2*3*4*5*6 从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("构造方法执行了");
    }
}  
 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值