Java语言基础-面向对象

面向对象

    区别:面向过程思想,强调的是过程(动作)。
                        面向对象思想,强调的是对象(实体)。过程封装在实体中。(C++、Java、C#)
    特点:
    1.面向对象就是一种常见的思想,符合人们的思考习惯
    2.面向对象的出现,将复杂的问题简单化
    3.面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者
    特征:封装、继承、多态

    类与对象的关系
    类:事物之间的描述;
    对象:该类事物的实例。在Java中是通过new来创建的。
    Java语言对现实生活中的事物进行描述,是通过类的形式来体现的。
    对于事物描述通常只关注两个放米娜:一个是属性,一个是行为。
    只要明确该事物的属性和行为并定义在类中结课。
    对象:其实就是该类事物实实在在存在的个体。

    成员变量和局部变量的区别:
    1.成员变量定义在类中,整个类中都可以访问,
        局部变量定义在函数、语句、局部代码块中,只在所属的区域有效;
    2.成员变量存在于堆内存的对象中,
        局部变量存在于栈内存的方法中;(笔记4 179行)
    3.成员变量随着对象的创建而存在,随着对象的消失而消失,
        局部变量随着所属区域的执行而存在,随着所属区域的结束而释放;
    4.成员变量都有默认初始化值,
        局部变量没有默认初始化值。

/*
   描述小汽车
   分析
   1.属性
       轮胎数、颜色
   2.行为
       运行

   定义类,其实就是在定义类中的成员。
   成员:成员变量<-->属性;成员函数<-->行为。
   */

   class Car
   {
       //封装的是数据,而不是类似num color的变量
       //属性和行为都是类的成员
       //属性  成员变量
       int num;    //默认初始化值为0
       String color;//String是类,而不是关键字;默认初始化值为null
       //行为  成员函数
       void run()
       {
           //int num=10;//在调用该方法时,栈内存中有num=10,则输出结果为10
           System.out.println(num+"..."+color);
       }
   }

   class  CarDemo
   {
       public static void main(String[] args)
       {
           //在计算机中创建一个car的实例,通过new关键字
           Car c=new Car();//c就是一个类类型的引用变量,指向了该类的对象
           c.num=4;
           c.color="blue";
           c.run();//要使用对象中的内容,可以通过  对象.成员  的相识来完成调用
           System.out.println("-------------------------------");

           Car c1=new Car();
           Car c2=new Car();
           show(c1);
           show(c2);
           c1.run();
           c2.run();
       }

       //汽车改装厂
       public static void show(Car c)//类类型的变量,一定指向对象,否则就是null
       {
           c.num=3;
           c.color="black";
       }
   }

    匿名对象,也就是没有名字的对象
        new Car();//匿名对象,其实就是定义对象的简写格式
        Car c=new Car();//这是有名字的对象
        c.run();//一个对象对方法进行一次调用
        可简化为
        new Car().run();
        使用方式
        1.当对象对方法仅进行一次调用的时候,就可以简化成匿名对象
        new Car().num=5;
        new Car().color="green";
        new Car().run();//结果为0...null
        2.匿名对象可以作为实际参数进行传递
        show(new Car());//此时show()方法中的形参c接收这个匿名对象

    数据类型传递的方法
   

//基本数据类型参数传递
   class Demo
   {
       public static void main(String[] args)
       {
           /*
           main进入栈,则x=3存在于栈内存中;show()经调用后弹栈,x=4随之弹栈
           */
           int x=3;
           show(x);
           System.out.println("x="+x);//输出结果为3
       }
       public static void show(int x)
       {
           x=4;
       }
   }

   //引用数据类型参数传递
   class Demo
   {
       int x=3;
       public static void main(String[] args)
       {
           Demo d=new Demo();
           d.x=9;
           show(d);//show()存在于栈内存,d.x存在于堆内存,故show()弹栈之后d.x=4仍旧存在于堆内存中
           System.out.println(d.x);//输出结果为4
       }
       public static void show(Demo d)
       {
           d.x=4;
       }
   }

    封装
        是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
        在Java中最小的封装体是函数。
        好处:
            将变化隔离;
            便于使用;
            提高重用行;
            提高安全性;
        封装原则
            将不需要对外提供的内容都隐藏起来;
            把属性都隐藏,提供公共方法对其访问。

    private
        私有,是一个权限修饰符,用于修饰类中的成员
        私有的内容,只在本类中有效,外界不能直接访问
        注意:私有仅仅是封装的一种体现
       

/*
人:
属性:
    年龄
行为:
    说话
*/
class Person
{
    /*
    private 私有,是一个权限修饰符,用于修饰类中的成员
    私有的内容,只在本类中有效,外界不能直接访问
    注意:私有仅仅是封装的一种体现
    */
    private int age;
    public void setAge(int a)
    {
        //外界无法直接访问age,通过本方法对age进行访问
        age=a;
    }
    public int getAge()
    {
        return age;
    }
    void speak()
    {
        System.out.println("age="+age);
    }
}
class  PersonDemo
{
    public static void main(String[] args) 
    {
        Person p=new Person();
        p.setAge(-20);
        p.speak();
    }
}

构造函数
    构建创造对象时使用的函数
    特点
    1.函数名与类名相同
    2.不用定义返回值类型
    3.没有具体的返回值
    作用
    给对象进行初始化
    注意
    1.默认构造函数的特点
    2.多个构造函数是以重载的形式存在的
    创建对象都必须通过构造函数初始化
    一个类中如果没有顶一个过构造函数,那么该类中会有一个默认的空参数的构造函数
    如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。

    一般函数和构造函数的区别
    构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。
    一般函数:对象创建后,需要函数功能时才调用。
   
    构造函数:对象创建时,只调用一次。
    一般函数:对象创建后,可以被调用多次。

    什么时候定义构造函数?
    在描述事物时,该事物一存在就具备的一些内容,这些内容定义在构造函数中
   

class Person
    {
            private String name;
            private int age;
            //定义一个Person的构造函数
            Person ()//构造函数,而且是空参数的
            {
        name="baby";
        age=1;
        System.out.println("person run");
        //return;    //结束函数
            }
            //有的孩子一出生就有名字
            Person(String n)
            {
        name=n;
            }

            Person(String n,int a)
            {
        name=n;
        age=a;
            }
            public void speak()
            {
        System.out.println(name+":"+age);
            }
            public void setName(String n)
            {
        name=n;
            }
    }


    class  ConsDemo
    {
        public static void main(String[] args) 
        {
            Person p=new Person();//构造函数在对象创建时就运行(给对像初始化)
            p.speak();
            Person p1=new Person("旺财");
            p1.speak();
            Person p2=new Person("小强",10);
            p2.speak();
        }
    }

    this关键字
    当成员变量和局部变量重名,可以用关键字this来区分
    this:代表当前对象。
    this就是所在函数所属对象的引用。
    简单来说,哪个对象调用了this所在的函数,this就代表哪个对象。
    this也可以用于在构造函数中调用其他构造函数
    注意:只能定义在构造函数的第一行。因为初始化动作要先执行。
    只要在本类中使用了本类的对象,通常使用this
   

class Person
    {
            private String name;
            private int age;
            //定义一个Person的构造函数
            Person ()//构造函数,而且是空参数的
            {
            name="baby";
            age=1;
            System.out.println("person run");
            //return;    //结束函数
            }
            //有的孩子一出生就有名字
            Person(String name)
            {
            this.name=name;//this.name是对象的name
            }

            Person(String n,int a)
            {
            this(name);//给该对象初始化name,对象间的调用,必须放在第一个语句
            age=a;
            }
            public void speak()
            {
            System.out.println(name+":"+age);
            }
            public void setName(String n)
            {
            name=n;
            }

            /*
            判断是否是同龄人
            */
            public boolean conpare(Person p)
        {
            return this.age==p.age;//this.age是p1的age,p.age是p2的age
        }
    }

    class ThisDemo 
    {
        public static void main(String[] args) 
        {
                //Person p=new Person("旺财");
                //p.speak();
                //Person p1=new Person("小强");
                //p1.speak();
            Person p1=new Person("aa",30);
            Person p2=new Person("cc",12);
            p2.conpare(p1);
        }
    }

   
    static(静态)关键字
    特点:
    1.static是一个修饰符,用于修饰成员;
    2.static修饰的成员被所有的对象所共享;
    3.static优先于对象存在,因为static的成员随着类的加载就已经存在了;
    4.static修饰的成员多了一种调用方式,就是可以直接被类名所调用;调用格式为类名.静态成员;
    5.static修饰的数据是共享数据,对象中存储的是特有数据;

    成员变量和静态变量的区别
    1.两个变量的生命周期不同
         成员变量随着对象的创建而存在,随着对象的被回收而释放;
         静态变量会随着类的加载而存在,随着类的消失而消失;
    2.调用方式不同
         成员变量只能被对象调用,
         而对于静态变量,可以被对象调用,也可以被类名调用;
    3.别名不同
         成员变量,也称为实例变量;
         静态变量,又称为类变量(区别于类型变量);
    4.数据的存储位置不同
         成员变量数据存储在堆内存的对象中,所以也叫做对象的特有数据;
         静态变量数据存储在方法区(共享数据区)的静态区中,所以也叫对象的共享数据;

    static的使用情况
    1.静态变量
         当分析对象中所具备的成员变量的值都相同时,这时,这个成员就可以被静态修饰
         只要数据在对象中都是不同的,那就是对象的特有数据,必须存储在对象中,是非静态的;
         如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中,定义成静态的;

    2.静态函数
         函数是否用静态修饰,需参考一点,该函数功能是否访问到对象中的特有数据;
         简单来说,从源代码看,该功能是否需要访问非静态的成员变量,
         如果需要,该功能就是非静态的;否则,就可以将该功能定义为静态的;
         当然,也可以定义为非静态的,但是非静态需要被对象调用,而仅创建对象,调用非静态的、没有访问特有数据的方法,该对象的创建时没有意义的。
   
    静态代码块
    随着类的加载而执行,而且只执行一次
    作用
        用于给类进行初始化
   

class StaticCode
   {
       static int num;//只能进行赋值
       static
       {//不只能够赋值,还能够运算
           num=10;
           num*=3;
           System.out.println("hhhh");
       }
       void show()
       {
           System.out.println("show run");
       }
   }

   class Person
   {
       private String name;

       {//构造代码块,不同于static代码块。可以给所有对象进行初始化,创建了几个对象就执行几次
           //System.out.println("person run");
           cry();
       }
       Person()//构造函数是给对应的对象进行针对性的初始化
       {
           name="baby";
           //cry();
       }
       Person(String name)
       {
           this.name=name;
           //cry();
       }
       public void cry()
       {
           System.out.println("cry");
       }
       public void speak()
       {
           System.out.println("name:"+name);
       }
   }

   class  StaticCodeDemo
   {
       //static
       //{//在主函数之前执行(随着类的加载而执行)
           //System.out.println("a");
       //}
       public static void main(String[] args)
       {
           //new StaticCode().show();
           Person p1=new Person();
           Person p2=new Person("旺财");
           p1.speak();
           p2.speak();
       }
   }

           
    ※注意:
         1.静态方法只能访问静态成员(非静态既可以访问静态,又可以访问非静态);
         2.静态方法中不可以使用this或者super关键字(this代表对象,而静态方法存在时,对象尚不存在);
         3.主函数是静态的;
   

class Person
    {
        String name;//成员变量,又叫做实例变量
        static String country="CN";//静态变量,又叫做类变量。单独开辟空间存储country,被所有的对象所共享
        //不仅可以被对象使用,也可以被类名访问
        public void show() //如果使用static修饰,show()随着类的加载而存在,此时不存在对象,而name存在于对象中,故编译时会报错
        {
            System.out.println(country+":"+name);
            //System.out.println(Person.country+":"+this.name);
        }
    }

    class StaticDemo 
    {
        int num=4;
        public static void main(String[] args) 
        {
            Person p=new Person();//p是类类型变量,区别于类变量
            p.name="小强";
            p.show();
            System.out.println(p.country);
            System.out.println(Person.country);

            new StaticDemo().show();
        }

        public void show()
        {
            System.out.println(num);
        }
    }

    主函数特殊之处(public static void main(String[] args)
        1.格式是固定的;
        2.被jvm所识别和调用
        public:因为权限必须是最大的;
        static:虚拟机在调用主函数时不需要对象,直接用主函数所属类名调用即可;
        void:主函数没有具体的返回值;
        main:函数名,不是关键字,只是一个jvm识别的固定的名字;
        String[] args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型;
       

class MainDemo 
        {
            public static void main(String[] args) //new String[0],产生了数组实体,但是没有存储元素
            {
                System.out.println(args);//[Ljava.lang.String;@bdb503
                System.out.println(args.length);// 0
                System.out.println(args[0]);
            }
        }

    static (静态)关键字
    当编译器编译时,如果该类中使用了其他类,编译器会在CLASSPATH下或当前目录下查找使用的类,
    如果查找无此类,则继续查找与使用类的名字相同的*.java文件,并自动编译
   

class  ArrayToolDemo 
    {
        public static void main(String[] args) 
        {
            int[] arr={4,8,2,9,72,6};
            ArrayTool tool=new ArrayTool();

            int max=ArrayTool.getMax(arr);
            int index=ArrayTool.getIndex(arr,10);
            System.out.println("max="+max);
            System.out.println("index="+index);
        }
    }
    /**
    建立一个用于操作数组的工具类,其中包含着常见的对数组操作的函数,如:最值、排序等。
    @author C.C.
    @version v1.0
    */
    public class ArrayTool
    {
        private ArrayTool(){};//该类中的方法都是静态的,所以该类不需要创建对象,
                                            //为了保证不让其他程序创建该类对象,可以将该类的构造函数私有化

        /*
        获取整型数组的最大值。
        @param arr 接收一个元素为int类型的数组;
        @return 返回该数组中的最大元素值;
        */
        public static int getMax(int[] arr)//没有访问到特有数据,需加static
        {
            int maxIndex=0;
            for (int x=1;x<arr.length ;x++ )
            {
                if(arr[x]>arr[maxIndex])
                    maxIndex=x;
            }
            return arr[maxIndex];
        }

        /**
        对数组进行选择排序
        @param arr 接收一个元素为int类型的数组;
        */
        public static void selectSort(int [] arr)
        {
            for(int x=0;x<arr.length-1;x++)
            {
                for(int y=x+1;y<arr.length;y++)
                {
                    if(arr[x]>arr[y])
                        swap(arr,x,y);
                }
            }
        }

        /**
        用于给数组进行元素的位置指环
        @param arr 接收一个元素为int类型的数组;
        @param a int;
        @param b int;
        */
        private static void swap(int[] arr,int a,int b)
        {
            int temp=arr[a];
            arr[a]=arr[b];
            arr[b]=temp;
        }
        /**
        获取指定的元素在指定数组中的索引
        @param arr 接收一个元素为int类型的数组;
        @param key 要找的元素;
        @return 返回该元素第一次出现的位置,如果不存在,则返回-1;
        */
        public static int getIndex(int[] arr,int key)
        {
            for (int x=0;x<arr.length ;x++ )
            {
                if(arr[x]==key)
                    return x;
            }
            return -1;
        }

        /**
        将int数组转换成字符串
        格式是:{e1,e2,...};
        @param arr 接收一个元素为int类型的数组;
        @return 返回该数组的字符串表现形式
        */
        public static String arrayToString(int[] arr)
        {
            String str="[";

            for (int x=0;x<arr.length ;x++ )
            {
                if(x!=arr.length-1)
                {
                    str=str+arr[x]+",";
                }
                else
                    str=str+arr[x]+"]";
            }
            return str;
        }
    }

    javadoc -d myhelp -author -version ArrayTool.java //在当前目录下创建myhelp目录存放
    使用set classpath=.;c:\myclass    //包含已存在的类

posted on 2012-07-20 18:09  foolchen  阅读(303)  评论(0编辑  收藏  举报

导航