类与对象总结(上)

OOA向对象分析

OOD:向对象设计

OOP:向对象编程

向对象三特征

封装性:所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。简而之就是,内部操作对外部而不可(保护性)

继承性:继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

多态性:所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。(利用多态可以得到良好的设计)

面向对象最大特征:可以对现实生活进行抽象。

类与对象的定义与使

是指共性的概念,而对象指的是一个具体的、可以使用的事物。首先产生类(类是生产对象的蓝图),然后才可以产生对象。对象的所有行为,一定在类中进行了完整的定义。

类中的组成:属性(变量,描述每个对象的具体特点)、方法(操作的行为)

类的定义:

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 p1 = new Person();

Person p2 = new Person("Steven",25);

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

Person p = new Person("Steven",25);

System.out.println(p.name);

System.out.println(p.getPersonInfo());

只要出现了关键字new,就开辟了内存

Java中,所谓的性能调优,调整的就是内存问

对象内存分析

我们可以简单的将Java中的内存区域分为栈内存和堆内存两块区域(实际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 = "张三" ;

per.age = 18 ;

}

Person per = new Person();

只要出现了关键词new,表明在堆上分配了内存并且产生了Person类的对象per引用这部分内存。Per存放在栈上,存放的是name和age在堆上的内存地址

per.name = "张三" ;

per.age = 18 ;

通过per引用,设置堆中属性值

注意:对象(引用数据类型)必须在实例化后调用,否则会产生 NullPointerException (运行时错误),编译时不会出错

引用传递的本质:一块堆内存可以被多个栈内存所指向

Person per1 = new Person();

Person per2 = new Person();

per2 = per1 ;

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

所有的垃圾空间会不定期GC,GC会影响性能,所以开发之中一定要控制好对象的产生数量(无用的对象尽量少产生)

private实现封装

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

例:

使private封装属性

private String name;

private int age;

此时使用了private对属性进行了封装,要访问私有属性,按照Java的设计原则必须提供以下两种方法:

setter方法:主要用于进行属性内容的设置与修改

getter方法:主要用于属性内容的取得

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();

 }

}

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

类的设计原则

编写类时,类中的所有属性必须使用private封装。

属性若要被外部访问,必须定义setter、getter方法

构造方法

构造方法就是使用关键字new实例化新对象时来进行调用的操作方法

1.方法名称必须与类名称相同

2.构造方法没有返回值类型声明

3.每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)

构造方法无返回值,为什么没有void声明?

1.属性是在对象开辟堆内存时开辟的空间

2.构造方法是在使用new后调用的

3.普通方法是在空间开辟了、构造方法执行之后可以多次调用的

注意:编译器是根据程序结构来区分普通方法与构造方法的,所以在构造方法前没有返回值类型声明若类中定义了构造方法,则默认的无参构造将不再生成

构造方法重载

例:构造参数重载

public Person(){

System.out.println("===无参构造===");

}

public Person(String n){

name = n ; System.out.println("===有参构造===");

}

建议:若干构造方法,请按照参数个数升序或降序

在进行类定义时:①定义属性->②定义构造方法->③定义普通方法

匿名对象

new Person("张三",20).getPersonInfo();

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

对象属性的初始化方式:

  1. 提供一系列的get和set方法(public)
  2. 通过构造函数    1.为对象开辟内存      2.调用合适的构造函数--->构造函数不止一个构造函数可以发生重载

this关键字

  1. this调用本类属性
class Person{

private String name;

 private int age;

 public Person(String name,int age){

  this.name = name ;
  this.age = age ;

 }
}

当参数与类中属性同名时,类中属性方法被正确赋值。此时我们加上this关键字便可以正确给对象属性赋值。

2.this调用本类方法

1调用普通方法:this.方法名称(参数)

class Person{

private String name;

 private int age;

 public Person(String name,int age){

 this.name = name ;

 this.age = age ;

 this.print();//调用普通方法

}

 public void print(){

 System.out.println("*****************");

 }

}

虽然调用本类普通方法不需要加this也可以正常调用。但强烈建议加上,加上this的目的可以区分方法的定义来源(在继承中有用)

2)调用构造方法:this(参数)

在Java中,支持构造方法的互相调用(this)

class Person{

private String name;

 private int age;

public Person(){

System.out.println("********产生一个新的Person对象********");

 }

public Person(String name){

this();//调用本类无参构造

this.name = name ;

}

public Person(String name,int age){

 this(name);//调用本类有参构造

this.age = age ;

 }

}

使用this调用构造方法时请注意:

1this调用构造方法的语句必须在构造方法首行

2使用this调用构造方法时,请留有出

3. this表示当前对象引用

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

只要对象调用了本类中的方法,这个this就表示当前执行的对象 

static关键字

static类属性

例:实例属性的内存分析

class Person{
 String Country = "中国";
 String name;
 int age;
 public void getPersonInfo(){
 System.out.println("姓名:"+this.name+",年龄:"+this.age+",国
家:"+this.Country);
 }
}
public class Test{
 public static void main(String[] args) {
 Person p1 = new Person();
 p1.name = "张三" ;
 p1.age = 10 ;
 Person p2 = new Person();
 p2.name = "李四" ;
 p2.age = 20 ;
 p1.getPersonInfo();
 p2.getPersonInfo();
 }
}

传统属性所具备的特征:保存在堆内存中,且每个对象独享属性。

描述共享属性,只需在属性前添加static关键字即可

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

static String Country = "中国";

结论:

访问static属性(类属性)应使用类名称.属性名

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

此时,我们修改country属性,所有对象都同步此属性值:

Person.country = "中华民国" ;

定义类时,如何选择实例变量和类属性呢?

在定义类时,99%的情况都不会考虑static属性,以非static属性(即实例变量)为主

如果需要描述共享属性的概念,或者不受对象实例化控制,使用static

static类   

使用static定义的方法,直接通过类名称访问

例:观察static方法

class Person{

private static String country;

private String name;

 private int age;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

 public static void setCountry(String c){

country = c ;

}

 public void getPersonInfo(){

System.out.println("姓名:"+this.name+",年龄:"+this.age+",国家:"+this.country);

}

}

public class Test{

public static void main(String[] args) {

 Person.setCountry("中国");

 Person person = new Person("张三",20);

 person.getPersonInfo(); }

}

关于static方法有以下两点说明:

所有的static方法不允许调用static定义的属性或方法

所有的static方法允许访问static方法或属性

使用static定义方法只有一个目的:某些方法不希望受到对象的控制,即可以在没有实例化对象的时候执行(广泛存在于工具类中)。

 

猜你喜欢

转载自blog.csdn.net/weixin_43267837/article/details/89173913