类和对象1

类和对象(1

1.面向对象的编程

面向对象的三大特征:

1)封装:即把客观的事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类和对象对其进行操作;对不可信的类进行信息的隐藏。(内部操作对外部不可见)

2)继承:一种能力。可使用所有现有类的所有功能,且无需进行重新编写对功能进行扩展。

3)多态:值一个类实例的相同方法在不同情形下的不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的接口。

面向过程编程缺少了代码的可重用性设计。

名词拓展:

OO:面向对象

OOA:面向对象分析

OOD:面向对象设计

OOP:面向对象编程

2.类与对象的定义与使用

(1)类与对象

类:共性的概念;而对象指的是一个具体的,可使用的事物。先产生类,后有对象,对象的行为,一定在类中进行了定义。

类的组成:方法(操作行为)

          属性(变量;描述每个对象的具体特点)

类的语法:

      class 类名{

             属性1

             属性2

             ……

             属性n;

             方法1(){ }

             ……

           }

注:此时的方法不再由主类调用,而由对象直接调用。

生成对象的语法;

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

定义person

class Person1{

Public String name;

private int age;

public Person1(String name,int age){

this.name = name;

this.age = age;

}

public String myPrint(){

return "name= "+this.name+",age= "+this.age;

}

}

生成类的实例化对象:

       Person1 per = new Person1("张三",20);

调用实例变量与实例方法:

        System.out.println(per.name);//调用成员变量

System.out.println(per.myPrint());//调用成员方法

(2)对象内存分析

只要出现了new就分配了内存,java中所谓的性能调优即调整内存问题,如下进行对象的内存分析。

//对象的内存分析

class Person2{

String name;

int age;

public Person2(){

//构造方法

}

}

public class Test8{

public static void main(String[] args){

Person2 per = new Person2();

per.name = "lemon";

per.age = 18;

System.out.println("name= "+per.name+",age= "+per.age);

}

}

运行结果:

name= lemon,age= 18


对象(引用数据类型)必须在实例化以后才可调用,否则会抛出NullPointerExcertion异常(运行时错误)。且只有引用数据类型(数组、类、接口)才可产生此类异常。

3.private实现封装处理

封装是面向对象中最复杂的概念,使用private关键字对封装进行处理只是第一步。

    private实现对类中属性的封装(要想在主方法中获取到该属性的值,必须在private属性所在的类中提供settergetter方法)。如下例:

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

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

class Man{

//使用private封装属性

private String name;//私有属性

private int age;//私有属性

    public void setName(String n){

name = n;

}

    public String getName(){

return name;

}

    

    public void setAge(int a){

    if(a>=1 && a<=180){

    age =a;

    }else{

    age = 0;

    }

}

    public int getAge(){

    return age;

}

    public void myPrint(){

    System.out.println("name= " + name + ",age= " +age);

    }

}

public class Test8{

public static void main(String[] args){

Man per1 = new Man();

per1.setName("张三");

per1.setAge(18);

per1.myPrint();

}

}

运行结果:

name= 张三,age= 18

4.构造方法与匿名对象

1.产生对象的方法:

类名称 方法名称 =  new  类名称( )

针对以上定义作如下分析:


2.构造方法:

 使用关键字new实例化对象来进行调用的方法。应遵循如下规则:

(1)方法名称必须与类名相同。

(2)构造方法没有返回值类型。

(3)每一个类中至少存在一种构造方法,如若没有明确定义,则系统会给出一个默认的无参构造方法。(若类中定义了构造方法,则默认的无参构造方法不再生成

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

    现在类中的组成:属性、构造方法、普通方法

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

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

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

public void Person(){ }  //命名不标准的普通方法

public Person() { ]     //构造方法

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

构造方法的调用和内存分配基本是同时完成的,所以可以使用构造方法对类中的属性进行初始化操作,可避免多次的setter和getter方法调用。如下例:

//构造方法

class Man{

private String name;

private int age;

public Man(String n,int i){

name = n;

age = i;

}

public void myPrint(){

System.out.println("name= "+name+",age="+age);

}

}

public class Test8{

public static void main(String[] args){

Man per = new Man("lemon",18);

per.myPrint();

}

}

运行结果:

name= lemon,age=18

3.构造方法的重载

  参数的类型或个数不同(若干构造方法时按照参数的个数升序或降序)

//构造方法的重载

class Man{

private String name;

private int age;

public Man(){

System.out.println("我是无参构造方法");

}

public Man(String s){

System.out.println("我是带一个参数的构造方法");

}

public Man(String n,int i){

name = n;

age = i;

}

public void myPrint(){

System.out.println("name= "+name+",age="+age);

}

}

public class Test8{

public static void main(String[] args){

Man per1 =new Man();

Man per2 =new Man("lemon");

Man per = new Man("lemon",18);

per.myPrint();

}

}

运行结果:

我是无参构造方法

我是带一个参数的构造方法

name= lemon,age=18

 

一般定义类时:①定义属性->②定义构造方法->③定义普通方法

4.匿名对象: new Man("lemon",18).myPrint();

5.this 关键字

//this关键字

class Man{

private String name;

private int age;

public Man(String name,int age){

name = name;

age = age;

}

public void myPrint(){

System.out.println("name= "+name+",age="+age);

}

}

public class Test8{

public static void main(String[] args){

Man per = new Man("lemon",18);

per.myPrint();

}

}

运行结果:

name= null,age=0

this 关键字的用途:(只要在类中方法访问类中属性一定要加关键字this)

1)调用本类属性;

2)调用本类方法;

3)表示的当前方法

 

(1)this调用本类属性


有上述例子可以看出当构造方法中参数与类中属性同名的时候,则无法对其进行正确的赋值。在此时我们就可以使用this关键字便可以正确的给对象的属性赋值。即      

 

//this调用本类属性

class Man{

private String name;

private int age;

public Man(String name,int age){

this.name = name;

this.age = age;

}

public void myPrint(){

System.out.println("name= "+name+",age="+age);

}

}

public class Test8{

public static void main(String[] args){

Man per = new Man("lemon",18);

per.myPrint();

}

}

运行结果:

name= lemon,age=18

 

(2)this调用本类方法

 

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

     不需加this也可以直接调用,加上this以区分方法的定义来源。

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

    支持构造方法的互相调用,但应注意:this调用构造方法时必须放在构造方法首行;使用this调用构造方法时要留有出口

class Man{

private String name;

private int age;

public Man(){

System.out.println("*********调用构造方法*********");

}

public Man(String name){

this();//调用无参构造方法

this.name = name;

}

public Man(String name,int age){

this(name);//调用带一个参数的构造方法

this.age = age;

this.myPrint();//调用本类的普通方法

}

public void myPrint(){

System.out.println("*********调用普通方法*********");

}

public void printInfo(){

System.out.println("name= "+name+",age="+age);

}

}

public class Test8{

public static void main(String[] args){

Man per = new Man("lemon",18);

per.printInfo();

}

}

运行结果:

*********调用构造方法*********

*********调用普通方法*********

name= lemon,age=18

 

(3)this表示当前对象

 

只要this调用了本类的方法,this就表示当前正在执行的对象。

//this表示当前对象

//只要对象调用了本类的方法,this就表示当前正在执行的对象

class Man{

private String name;

private int age;

public void myPrint(){

System.out.println("当前对象: "+this);

}

}

public class Test8{

public static void main(String[] args){

Man man1 = new Man();

System.out.println("主方法 "+ man1);

man1.myPrint();

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

Man man2 = new Man();

System.out.println("主方法:"+man2);

man2.myPrint();

}

}

运行结果:

主方法 test.Man@6d06d69c

当前对象: test.Man@6d06d69c

******************

主方法:test.Man@7852e922

当前对象: test.Man@7852e922

 

6.static关键字

static可以修饰属性和方法

1static属性(类属性)

实例变量(传统属性)(保存在堆空间中,且每个对象独享属性)

class Man{

String country = "China";

String name;

int age;

public void myPrint(){

System.out.println("name= "+this.name+",age= "

                       +this.age+",country= "+country);

}

}

public class Test8{

public static void main(String[] args){

Man man1 = new Man();

Man man2 = new Man();

man1.name = "demon";

man2.name = "lemon";

man1.age = 16;

man2.age = 18;

man1.myPrint();

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

man2.myPrint();

}

}

运行结果:

name= demon,age= 16,country= China

***********************************

name= lemon,age= 18,country= China

实例变量(传统属性)的内存分析:


共享属性(保存在全局数据区的内存中,所有对象都可以对该区域进行访问)

    若对country属性加上static属性,则使其成为共享属性。

修改上述代码:static String country = "China";

则内存分析图如下:


注意:

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

所有的非static属性(类属性)必须在对象实例化后才可使用,而static(类属性)可以在对象未初始化的时候使用。

在此时若修改(static String country = “China”)的值,所有的对象都同步的得到修改。

 

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

99%的情况下不会考虑static属性,而使用非static属性。

如果要描述共享属性,或者不受对象实例化的影响可以使用static属性。

 

(2)static方法(类方法)

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

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

    使用static方法的目的: 某些方法不想受到类的控制,即没有实例化对象就可以执行。

//static方法

class Man{

private static String country = "China";

private String name;

private int age;

public Man(String name,int age){

this.name = name;

this.age =age;

}

public static void setCountry(String C){

country = C;

}

public void myPrint(){

System.out.println("name= "+this.name+",age= "

                       +this.age+",country= "+country);

}

}

public class Test8{

public static void main(String[] args){

Man.setCountry("China");

Man man = new Man("demon",26);

man.myPrint();

}

}

运行结果:

name= demon,age= 26,country= China


原文地址:https://www.cnblogs.com/edda/p/12597878.html