类与对象(一)

类与对象:

  • 基本概念:类是具有共性的对象的共性抽象,而对象是指一个具体的,可以使用的事 物。
    对象一定来自于某个类
    对象是类的实例化

  • 类中的组成:属性(变量,描述每个对象的具体特点)
    方法(对象可执行的过程)

  • 类的定义与使用
    类的定义:访问权限 class 类名{
    定义数据(即属性);
    定义方法;
    }

    此时的方法不再有类直接调用,而需要由对象调用。

    数据的定义:访问权限 数据类型 属性名;

    方法的定义:访问权限 数据类型 方法名(形参){
    方法体;
    }

例如:People类的定义:

         class  People{
              private String name;
              private int age;
              public People(String name,int age){
                this.name = name;
                this.age = age;
                     }
             public void getInfo(){
             System.out.println("姓名"+this.name +",年龄"+this.age);
                      }
          }
  • 对象的定义:类名称 对象名称 = new 类名称(实参);

         以People类为例,我们可以产生如下People类的实例:
            People p1 = new People();
            People p2 = new People(“小白”,10);
         通过对象调用实例变量与实例方法:
            People p= new People(“小白”,10);
            //p.name 对象调用实例
            System.out.println(p.name);
            //p.getInfo()  对象调用方法
            System.out.println(p.getInfo());
    
  • 对象的产生需要两步:
    1.为对象分配内存空间
    2.调用合适的构造函数

    我们先来看看怎样为对象分配内存空间:

    我们先简单的将Java内存区域分为栈内存和堆内存两块区域:

    栈内存(虚拟机局部变量表):存放的是局部变量(包含编译期可知的各种基本数据类型、引用对象-即堆内存地址),Java栈是与线程对应起来的,每当创建一个线程,JVM就会为这个线程创建一个对应的Java栈。

    堆内存:保存的是真正的数据,即对象的属性信息。

    下面通过代码和分析图来讲述是如何为对象分配内存的:

     Class  Student{
          String name;
          int id;
    }
         public class Test{
            public static void main(){
               Student stu = new Student();
               stu.name = “小白”;
               stu.id = 1;
     }
    }
    

    内存图如下:
    在这里插入图片描述

    对象必须实例化后调用,否则会产生NullPointerEcception(运行时错误)

  • 引用传递分析:
    在这里插入图片描述
    引用传递的本质:一块堆内存可以被多个栈空间所指向

    垃圾空间:没有任何栈内存指向的堆内存空间

    所有的垃圾空间会不定期GC,GC会影响性能,所以无用的对象尽量少产生。

  • 封装和构造方法

    private实现封装:要使内部操作对外部不可见(对象不可直接操作属性),可以用private进行封装。

    使用private封装属性:

         private  String  name;
         private  int  age;
    

    此时要访问私有属性,按照java的设计原则必须提供两种方法:

    1.setter方法:主要用于进行属性内容的设置与修改
    2. getter方法:主要用于属性内容的取得

       class Student{
           private String name;
           private int id;
    
           public String getName() {
               return name;
               }
    
           public void setName(String name) {
                this.name = name;
             }
    
            public int getId() {
                 return id;
            }
    
            public void setId(int id) {
                 this.id = id;
            }
    
             public void getStudent() {
                  System.out.println("姓名:"+name+",学号:"+id);
             }
       }
       public class Test {
          public static void main(String[] args) {
              Student stu = new Student();
              stu.setName("小白");
              stu.setId(1);
              stu.getStudent();
           }
        }
    

    private实现封装的最大特征在于:只允许本类访问,不允许外部类访问。

    类的设计原则:编写类时,类中的所有属性必须使用private封装
    属性若要被外部访问,必须定义setter、getter方法。

  • 构造方法:

    构造方法的定义
    1.方法名与类名同名
    2.构造方法没有返回值类型
    3.每个类中一定至少存在一个构造方法(没有明确定义,系统会自动生成无参构造,若类中定义了构造方法,则默认的无参构造将不再生成)

    为什么构造方法没有返回值类型?那是因为编译器根据程序结构来区分普通方法和构造方法的,所以在构造方法前不加返回值类型声明。

    构造方法的调用和对象内存分配几乎时同时完成的,因此我们乐意利用构造方法来为类中的属性进行初始化构造(可避免多次setter方法调用)

    构造方法的重载:

    重载的特点:访问权限相同,函数名相同,参数列表相同,返回值不做要求

    例如:

      public People(){
         System.out.println(“这是无参构造”);
        }
      public People(String name){
         System.out.println(“这是带参构造”);
        }
    

    现在我们可以看到,定义一个类的顺序:定义属性—>定义构造方法—>定义普通方法

  • 匿名对象

    就是没有名字的对象,由于匿名对象不会有任何的栈空间指向,所以使用一次后就成为垃圾空间。

       new People(“张三”,20).getPeople();
    
  • this关键字

    this关键字的三个用途

    this调用本类属性
    this调用本类方法
    this表示当前对象

    this调用本类属性:当参数与类中属性同名时,类中属性就无法被正确赋值,这是我们加上this关键字就可以给对象正确赋值。

           class People{
                private String name;
                private int age;
                public People(String name,int age){
                     name = name;
                    age = age;
             }
                public String getPeo(){
                   return "姓名:" + name + ",年龄" + age;
             }
                public void print(){
                   System.out.println("==================");
            }
           }
           public class Test {
                  public static void main(String[] args) {
                       People people = new People("小白",20);
                        System.out.println(people.getPeo());
                     }
              }
    

    上段代码我们可以发现输出为:姓名:null,年龄0

    所以我们需要加上this

     public People(String name,int age){
       this.name = name;
       this.age = age;
       }
    

    this调用本类方法
    1.调用普通方法:this.方法名称(参数)
    2.调用构造方法:this(参数)

    class People{
       private String name;
       private int age;
       public People(String name,int age){
       this.name = name;
       this.age = age;
       //this调用普通方法
       this.print();
      }
     public String getPeo(){
       return "姓名:" + name + ",年龄" + age;
       }
      public void print(){
       System.out.println("==================");
       }
    }
    public class Test {
         public static void main(String[] args) {
                 People people = new People("小白",20);
                 System.out.println(people.getPeo());
          }
      }
    

    this调用构造方法时请注意
    1.this调用构造方法的语句必须在语句首行;
    2.使用this调用构造方法时,请留有出口

    this代表当前对象其实就是代表当前对象的引用:

    例如:

    class People{
           public void printf() {
               System.out.println("[print]方法:" + this);
              }
        }
    
    public class Test {
           public static void main(String[] args) {
               People p1 = new People();
               System.out.println("[main]方法:"+p1);
               p1.printf();
               System.out.println("==============");
               People p2 = new People();
               System.out.println("[main]方法:"+p2);
              p2.printf();
              }
       }
    

    结果:
    [main]方法:People@4554617c//后面这个数值为p1对象内存地址的哈希码
    [print]方法:People@4554617c
    ==============
    [main]方法:People@74a14482
    [print]方法:People@74a14482

  • static关键字

    我们前面说到的传统属性所具备的特征就是保存在堆内存中,并且每个对象独享属性,如果想让这些属性成为共享的,那么只需在属性前加上static关键字即可。

    static属性又称类属性,保存在全局数据区中,所有对象都可以进行该数据区的访问。

    例如:

    class People{
            static String  Country = "中国";
            private String name;
            private int age;
            public People (String name,int age){
                 this.name = name;
                 this.age = age;
               }
           public void getPeo() {
                 System.out.println("姓名:" + this.name + ",年龄" + this.age + ",国籍:" + Country);
             }
        }
     public class Test {
              public static void main(String[] args) {
                          People p1 = new People("小白",10);
                          People p2 = new People("小黑",10);
                          p1.getPeo();
                          p2.getPeo();
         }
    

    其内存分析如下:
    在这里插入图片描述
    访问static属性(类属性)应使用类名称.属性名

    所有的非static属性必须在对象实例化后使用,而static属性不受对象实例化控制

    static类方法:类名.方法名直接访问

    关于static方法有以下两点要注意:
    所有的static方法不允许调用非static定义的属性和方法;
    所有的非static方法允许访问static方法或属性

    使用static方法的目的只有一个:某些方法不希望收到对象的控制,即可在没有实例化对象的时候执行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值