• 类和对象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


  • 相关阅读:
    BZOJ1930 [Shoi2003]pacman 吃豆豆
    hdu5322 Hope
    hdu5390 tree
    hdu4609 3-idiots
    hdu5354 Bipartite Graph
    hdu4918 Query on the subtree
    hdu5314 Happy King
    [题解] PowerOJ 1741 最长递增子序列问题 (最大流)
    [题解] PowerOJ 1740 圆桌问题 (最大流)
    [题解] PowerOJ 1739 魔术球问题 (最大流)
  • 原文地址:https://www.cnblogs.com/edda/p/12597878.html
Copyright © 2020-2023  润新知