面向对象编程——类与对象(定义、使用、封装、构造方法)

面向对象编程——类与对象(定义、使用、封装、构造方法)
学面向对象这块时,老师经常说:要学好面向对象,首先你得有个对象……(突然的扎心。。。)

言归正传,面向对象就是对现实生活的抽象,面向对象有三大特征:
1.封装:将客观事物封装为抽象的类,并且类可以将自己的数据与方法只对可信的类开放,对不可信的进行隐藏。简单来说就是内部操作对外部不可见,强调的是保护性。
2.继承:继承描述的是这样一种能力:可以使用仙有类的所有功能,并在无需重新编写原有类的情况下进行功能上的扩展。(要使用继承,必须满足is-a原则)
3.多态:一个类实例的相同方法在不同情形下有不同的表现形式(比如:方法重载,就是多态的一种,方法名相同,参数类型或个数不同)

java是一门面向对象编程的语言,在java的世界里,一切皆对象

上面只是热个身,这篇博客的重点在于类与对象

一、类与对象的定义与使用
1.概念:所谓类就是指共性的概念,由方法和属性组成。对象是指一个具体的、可以使用的事物。首先产生类,而后产生对象,对象所具备的所有行为,一定在类中进行了完整定义。
2.定义
定义一个类的语法如下:

class  类名称{
     属性1;
     属性2;
     属性n……;
     方法1(){}
     方法2(){}
     方法n(){}……
}

如上就是一个类的完整定义,此时的方法不再由主类直接定义。
例如:Person类的定义

class Person{
      public String name;
      public int age;
      public Person(String name,int age){
            this.name=name;
            this.age=age;
      }
      public String getPersonInfo(){
             return"姓名:"+this.name+",年龄:"+this.age;
      }
}

有了类,我们就可以定义对象了:

类名称  对象名称=new  类名称();

以Person类为例,我们可以产生一个Person类的对象:

Person p1=new Person();
Person p2=new Person("tony",18);

通过对象调用实例变量与实例方法:

Person p=new Person("tony",18);
System.out.println(p.name);
System.out.println(p.getPersonInfo());

只要出现了关键字new,就表示在堆上开辟了内存
3.对象内存分析
在这可以简单的将java中的内存区域分为栈内存和堆内存。
——栈内存(虚拟机局部变量表):存放方法的局部变量、方法形参、引用(java栈是与线程对应起来的,每当创建一个线程,JVM就会为这个线程创建一个对应的java栈)
——堆内存(所有的方法共享此内存):保存的是真正的数据,即对象的属性信息。
看一下这段代码:

class Person{
    String name;
    int age;
    }
 public class Test{
      public static void main(String[] args){
            Person per=new Person();
            per.name="tony";
            per.age=18;
     }
}

main方法中的第一行代码,出现了关键字new,表示在堆上分配了内存并且产生Person类的对象per引用这部分内存,内存图如下:(画的太丑,将就看看~)
面向对象编程——类与对象(定义、使用、封装、构造方法)
接下来两句代码

per.name="tony";
per.age=18;

内存图如下:
面向对象编程——类与对象(定义、使用、封装、构造方法)
所有的数据类型必须在实例化后调用,否则会抛出NullPointerException(运行时异常),编译不会出错。
4.引用传递分析
本质:一块堆内存可以被多个栈所指向
例如:

Person per1=new Person();
Person per2=new Person();
per1=per2;

前两句代码的内存图如下:
面向对象编程——类与对象(定义、使用、封装、构造方法)
在执行了per1=per2后,内存会如何变化:
面向对象编程——类与对象(定义、使用、封装、构造方法)
可以看到,会产生垃圾空间,没有任何栈内存指向的堆内存空间。

二、封装与构造方法
1.private实现封装
先看一段无封装代码:

class Person{
    String name;
    int age;
    public void getPersonInfo(){
        System.out.println("姓名:"+name+",年龄:"+age);
    }
}
public class Test{
   public static void main(String[] args){
        Person person=new Person();
        person.name="张三";
        person.age=-200;
        person.getPersonInfo();
   }
}

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

private String name;
private int age;

此时,只能内部访问。若想访问私有属性,按照java的设计原则必须提供一下两种方法:
*setter方法:主要用于进行属性内容的设置与修改
*getter方法:主要用于属性内容的取得
扩展的Person类内容:

class Person{    
         private String name;   
         private int age;
         public void setName(String n){
                 name = n ;
                     }
         public String getName(){
                 return name;
                     }
         public void setAge(int i){
                  if (i>0&&i<=200) {  
                            age = i ;
                  }else {
                        age = 0 ;
                }
           }
           public int getAge(){
                   return age;
           }
           public void getPersonInfo(){
              System.out.println("姓名:"+name+",年龄:"+age);
        }
 }
 public class Test{
     public static void main(String[] args){
           Person person=new Person();
           person.setName("张三");
           person.setAge(-200);
           person.getPersonInfo();
     }
 }

2.构造方法
1)定义:所谓构造方法就是使用关键字new实例化新对象时来进行调用的操作方法。
2)遵循原则:
方法名必须与类名称相同
构造方法没有返回值类型声明
每一个类中至少存在一个构造方法(没有明确定音,则系统自动生成一个无参构造)
3)作用:为类中属性进行初始化,避免多次的setter调用
3.构造方法重载(参数个数不同)

publlic Person(){
    System.out.println("---无参构造---");
}
public Person(String n){
    name=n'
    System.out.println("---有参构造---");
}

4.匿名对象:没有任何的栈空间所指向,使用一次后就成为垃圾空间。

之后的几个重要关键字下篇写~~