博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
07-01 Java 封装
阅读量:7014 次
发布时间:2019-06-28

本文共 19649 字,大约阅读时间需要 65 分钟。

1:成员变量和局部变量的区别
/*    成员变量和局部变量的区别?        A:在类中的位置不同            成员变量:在类中方法外            局部变量:在方法定义中或者方法声明上        B:在内存中的位置不同            成员变量:在堆内存            局部变量:在栈内存        C:生命周期不同            成员变量:随着对象的创建而存在,随着对象的消失而消失            局部变量:随着方法的调用而存在,随着方法的调用完毕而消失        D:初始化值不同            成员变量:有默认初始化值            局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。                    注意事项:            局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。*/class Varialbe {    //成员变量    //int num = 10;    int num; //0        public void show() {        //int num2 = 20; //局部变量        //可能尚未初始化变量num2        int num2; //没有默认值        // int num2 = 20;        System.out.println(num2);//这里报错,num2没有默认值                int num = 100;        System.out.println(num);    }}class VariableDemo {    public static void main(String[] args) {        Varialbe v = new Varialbe();                System.out.println(v.num); //访问成员变量                v.show();                    }}

 

2:类作为形式参数的问题

如果你看到一个方法需要的参数是一个类名,就应该知道这里实际需要的是一个具体的对象。

/*    形式参数的问题:        基本类型:形式参数的改变不影响实际参数        引用类型:形式参数的改变直接影响实际参数*///形式参数是基本类型class Demo {    public int sum(int a,int b) {        return a + b;    }}//形式参数是引用类型class Student {    public void show() {        System.out.println("我爱学习");    }}class StudentDemo {    //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。    public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();        s.show();    }}class ArgsTest {    public static void main(String[] args) {        //形式参数是基本类型的调用        Demo d = new Demo();        int result = d.sum(10,20);        System.out.println("result:"+result);        System.out.println("--------------");                //形式参数是引用类型的调用        //需求:我要调用StudentDemo类中的method()方法        StudentDemo sd = new StudentDemo();        //创建学生对象        Student s = new Student();        sd.method(s); //把s的地址给到了这里    }}

3:匿名对象

/*    匿名对象:就是没有名字的对象。        匿名对象的应用场景:        A:调用方法,仅仅只调用一次的时候。            注意:调用多次的时候,不适合。因为会重新生成对象            那么,这种匿名调用有什么好处吗?                有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。        B:匿名对象可以作为实际参数传递*/class Student {    public void show() {        System.out.println("我爱学习");    }}class StudentDemo {    public void method(Student s) {        s.show();    }}class NoNameDemo {    public static void main(String[] args) {        //带名字的调用        Student s = new Student();        s.show();        s.show();        System.out.println("--------------");                //匿名对象        //new Student();        //匿名对象调用方法        new Student().show();        new Student().show(); //这里其实是重新创建了一个新的对象        System.out.println("--------------");                        //匿名对象作为实际参数传递        StudentDemo sd = new StudentDemo();        //Student ss = new Student();        //sd.method(ss); //这里的s是一个实际参数        //匿名对象        sd.method(new Student());                //在来一个        new StudentDemo().method(new Student());     }}
4:封装和private
封装(理解)    (1)隐藏实现细节,提供公共的访问方式    (2)好处:        A:隐藏实现细节,提供公共的访问方式        B:提高代码的复用性        C:提高代码的安全性    (3)设计原则        把不想让外界知道的实现细节给隐藏起来,提供公共的访问方式    (4)private是封装的一种体现。        封装:类,方法,private修饰成员变量private关键字(掌握)    (1)私有的意义,可以修饰成员变量和成员方法    (2)特点:        被private修饰的后的成员只能在本类中被访问    (3)private的应用:        以后再写一个类的时候:            把所有的成员变量给private了            提供对应的getXxx()/setXxx()方法

 

 

private的引出

/*    定义一个学生类:        成员变量:name,age        成员方法:show()方法            我们在使用这个案例的过程中,发现了一个问题:        通过对象去给成员变量赋值,可以赋值一些非法的数据。        这是不合理的。        应该是这个样子的:在赋值之前,先对数据进行判断。        判断到底在哪里做比较合适呢?        StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。            所以,这个判断应该定义在Student类中。        而我们在成员变量的位置可不可以进行数据判断呢?        是不可以的,因为做数据校验,必须要依靠一些逻辑语句。        逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法        来对数据进行校验。        按照我们前面的分析,我们给出了一个方法进行校验。    但是呢,它偏偏不调用方法来赋值,还是直接赋值了,    这样我们的方法就没有起到作用。    我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。    怎么去强制要求不能直接使用成员变量呢?        针对这种情况,Java就提供了一个关键字 private            private:私有的。可以修饰成员变量和成员方法。        注意:被private修饰的成员只能在本类中访问。            其实我讲到现在讲解的是一个封装的思想。    封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。*/class Student {    //姓名    String name;    //年龄    private int age;        //写一个方法对数据进行校验    /*        返回值类型:void        参数列表:int a    */    public void setAge(int a) {        if(a < 0 || age > 120) {            System.out.println("你给的年龄有问题");        }else {            age = a;        }    }            //show()方法,显示所有成员变量值    public void show() {        System.out.println("姓名:"+name);        System.out.println("年龄:"+age);    }}class StudentDemo {    public static void main(String[] args) {        //创建学生对象        Student s = new Student();        s.show();        System.out.println("--------------");                //给成员变量赋值        s.name = "林青霞";        //s.age = 27;        s.setAge(27);        s.show();        System.out.println("--------------");                //给age赋值        //s.age = -27; //这个数据是不合理的        //通过方法给值        s.setAge(-27);//你给的年龄有问题        s.show();        System.out.println("--------------");    }}

封装和private的使用

/*    封装和private的应用:        A:把成员变量用private修饰        B:提高对应的getXxx()和setXxx()方法*///定义学生类class Student {    //姓名    private String name;    //年龄    private int age;        //姓名获取值    public String getName() {        return name;    }        //姓名设置值    public void setName(String n) {        name = n;    }        //年龄获取值    public int getAge() {        return age;    }        //年龄赋值    public void setAge(int a) {        age = a;    }}//测试类class StudentTest {    public static void main(String[] args) {        //创建学生对象        Student s = new Student();                //使用成员变量        //错误:被私有修饰了,外界不能直接访问了        //System.out.println(s.name+"---"+s.age);        System.out.println(s.getName()+"---"+s.getAge());                //给成员变量赋值        //s.name = "林青霞";        //s.age = 27;        //通过方法给赋值        s.setName("林青霞");        s.setAge(27);        System.out.println(s.getName()+"---"+s.getAge());    }}
6:this关键字和内存图解
(1)代表当前类的引用对象        记住:哪个对象调用方法,该方法内部的this就代表那个对象    (2)this的应用场景:        A:解决了局部变量隐藏成员变量的问题        B:其实this还有其他的应用,明天讲解。

this关键字使用

/*    标准的代码改进版        this:哪个对象调用那个方法,this就代表那个对象*/class Student {    private String name;    private int age;        public String getName() {        return name; //这里其实是隐含了this,this.name    }        public void setName(String name) {        this.name = name;    }        public int getAge() {        return age;    }        public void setAge(int age) {        this.age = age;    }}class StudentTest2 {    public static void main(String[] args) {        //创建一个对象        Student s1 = new Student();        s1.setName("林青霞");        s1.setAge(27);        System.out.println(s1.getName()+"---"+s1.getAge());                //创建第二个对象        Student s2 = new Student();        s2.setName("刘意");        s2.setAge(30);        System.out.println(s2.getName()+"---"+s2.getAge());    }}

this 内存图解:

 

 7:构造方法

7:构造方法(掌握)    (1)作用:用于对对象的数据进行初始化    (2)格式:        A:方法名和类名相同        B:没有返回值类型,连void都不能有        C:没有返回值                思考题:构造方法中可不可以有return语句呢?        可以。而是我们写成这个样子就OK了:return;        其实,在任何的void类型的方法的最后你都可以写上:return;    (3)构造方法的注意事项        A:如果我们没写构造方法,系统将提供一个默认的无参构造方法        B:如果我们给出了构造方法,系统将不再提供默认构造方法            如果这个时候,我们要使用无参构造方法,就必须自己给出。            推荐:永远手动自己给出无参构造方法。    (4)给成员变量赋值的方式        A:setXxx()        B:带参构造方法    (5)标准案例        class Student {            private String name;            private int age;                        public Student(){}                        public Student(String name,int age) {                this.name = name;                this.age = age;            }                        public String getName() {                return name;            }                        public void setName(String name) {                this.name = name;            }                        public int getAge() {                return age;            }                        public void setAge(int age) {                this.age = age;            }        }                测试:        class StudentDemo {            public static void main(String[] args) {                //方式1                Student s1 = new Student();                s1.setName("林青霞");                s1.setAge(27);                System.out.println(s1.getName()+"---"+s1.getAge());                                //方式2                Student s2 = new Student("刘意",30);                System.out.println(s2.getName()+"---"+s2.getAge());            }        }

 

 构造方法

/*    构造方法:        给对象的数据进行初始化    格式:        A:方法名与类名相同        B:没有返回值类型,连void都没有        C:没有具体的返回值*/class Student {    private String name; //null    private int age; //0      //没有返回值类型,连void都没有    public Student() {        System.out.println("这是构造方法");    }}class ConstructDemo {    public static void main(String[] args) {        //创建对象        Student s = new Student();        System.out.println(s); //Student@e5bbd6    }}

构造方法的重载和注意事项

/*    我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢?        构造方法的注意事项:        A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。        B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。            注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法            给成员变量赋值有两种方式:        A:setXxx()        B:构造方法*/class Student {    private String name;    private int age;    public Student() {        //System.out.println("我给了,你还给不");        System.out.println("这是无参构造方法");    }        //构造方法的重载格式    public Student(String name) {        System.out.println("这是带一个String类型的构造方法");        this.name = name;    }        public Student(int age) {        System.out.println("这是带一个int类型的构造方法");        this.age = age;    }        public Student(String name,int age) {        System.out.println("这是一个带多个参数的构造方法");        this.name = name;        this.age = age;    }        public void show() {        System.out.println(name+"---"+age);    }}class ConstructDemo2 {    public static void main(String[] args) {        //创建对象        Student s = new Student();        s.show();        System.out.println("-------------");                //创建对象2        Student s2 = new Student("林青霞");        s2.show();        System.out.println("-------------");                //创建对象3        Student s3 = new Student(27);        s3.show();        System.out.println("-------------");                //创建对象4        Student s4 = new Student("林青霞",27);        s4.show();    }}

8、成员方法

/*    类的组成:成员变量,成员方法    今天我们又加入了一个新的成员:构造方法。    以后再提类的组成:        1、成员变量        2、构造方法        3、成员方法            根据返回值:                void类型                非void类型            形式参数:                空参方法                非空参方法*/class Student {    public String getString() {        return "helloworld";    }    public void show() {        System.out.println("show");    }        public void method(String name) {        System.out.println(name);    }        public String function(String s1,String s2) {        return s1+s2;    }}class StudentDemo {    public static void main(String[] args) {        //创建对象        Student s = new Student();                //调用无参无返回值方法        s.show();                //调用无参有返回值方法        String result = s.getString();        System.out.println(result);                //调用带参无返回值的方法        s.method("林青霞");                //调用带参带返回值的方法        String result2 = s.function("hello","world");        System.out.println(result2);    }}

9、一个标准学生类的代码及测试

/*    一个标准代码的最终版。        学生类:        成员变量:            name,age        构造方法:            无参,带两个参        成员方法:            getXxx()/setXxx()            show():输出该类的所有成员变量值                给成员变量赋值:        A:setXxx()方法        B:构造方法            输出成员变量值的方式:        A:通过getXxx()分别获取然后拼接        B:通过调用show()方法搞定*/class Student {    //姓名    private String name;    //年龄    private int age;        //构造方法    public Student() {    }        //构造方法    public Student(String name,int age) {        this.name = name;        this.age = age;    }    //带返回值的成员方法    public String getName() {        return name;    }        //不带返回值的成员    public void setName(String name) {        this.name = name;    }        public int getAge() {        return age;    }        //带参数的成员方法    public void setAge(int age) {        this.age = age;    }        //输出所有的成员变量值    public void show() {        System.out.println(name+"---"+age);    }}//测试类class StudentTest {    public static void main(String[] args) {        //方式1给成员变量赋值        //无参构造+setXxx()        Student s1 = new Student();        s1.setName("林青霞");        s1.setAge(27);        //输出值        System.out.println(s1.getName()+"---"+s1.getAge());        s1.show();        System.out.println("----------------------------");                //方式2给成员变量赋值        Student s2 = new Student("刘意",30);        System.out.println(s2.getName()+"---"+s2.getAge());        s2.show();    }}

10、代码:Student s = new Student();做了哪些事情?

创建对象做了哪些事情?

(1)把Student.class文件加载到内存    (2)在栈内存为s开辟空间    (3)在堆内存为学生对象申请空间    (4)给学生的成员变量进行默认初始化。null,0    (5)给学生的成员变量进行显示初始化。林青霞,27    (6)通过构造方法给成员变量进行初始化。刘意,30    (7)对象构造完毕,把地址赋值给s变量

图解:

 

 

11、变量什么时候定义为成员变量:

如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。

变量到底定义在哪里好呢?

变量的范围是越小越好。因为能及时的被回收。

 

//方式1/*class Demo {	public int sum() {		int a = 10;		int b = 20;		int c = a + b;		return c;	}}*///方式1满足了我们的要求,但是不好。//因为参与操作的数据现在是固定的。//方式2  --推荐/*class Demo {	public int sum(int a,int b) {		return a + b;	}}*///方式2可以满足我们的要求,但是呢我们学习过来面向对象的思想。//我就再想,a,b可不可以定义为成员变量呢?//如果可以,我们再改进一版class Demo {	int a;	int b;		public int sum() {		return a + b;	}}//虽然这种方式可以,并且好像是符合了面向对象的思想。//但是不好。//因为我们曾经说过:类是一组相关的属性和行为的集合。//并且类是通过事物转换过来的//而类中的成员变量就是事物的属性//属性是用来描述事物的//同理:成员变量其实是用来描述类的。

  

 长宽是描述长方形这个类的信息,应该定义为成员变量:

/*    定义一个长方形类,定义 求周长和面积的方法,    然后定义一个测试了Test2,进行测试。    长方形的类:        成员变量:            长,宽        成员方法:            求周长:(长+宽)*2;            求面积:长*宽                注意:        import必须出现在所有的class前面。*/import java.util.Scanner;class ChangFangXing {    //长方形的长    private int length;    //长方形的宽    private int width;        public ChangFangXing(){}        //仅仅提供setXxx()即可    public void setLength(int length) {        this.length = length;    }        public void setWidth(int width) {        this.width = width;    }        //求周长    public int getZhouChang() {        return (length + width) * 2;    }        //求面积    public int getArea() {        return length * width;    }}class Test2 {    public static void main(String[] args) {        //创建键盘录入对象        Scanner sc = new Scanner(System.in);                System.out.println("请输入长方形的长:");        int length = sc.nextInt();        System.out.println("请输入长方形的宽:");        int width = sc.nextInt();                //创建对象        ChangFangXing cfx = new ChangFangXing();        //先给成员变量赋值        cfx.setLength(length);        cfx.setWidth(width);                System.out.println("周长是:"+cfx.getZhouChang());        System.out.println("面积是:"+cfx.getArea());    }}

12、static关键字

10:static关键字(理解)    (1)静态的意思。可以修饰成员变量和成员方法。    (2)静态的特点:        A:随着类的加载而加载        B:优先与对象存在        C:被类的所有对象共享            这其实也是我们判断该不该使用静态的依据。            举例:饮水机和水杯的问题思考        D:可以通过类名调用            既可以通过对象名调用,也可以通过类名调用,建议通过类名调用。    (3)静态的内存图        静态的内容在方法区的静态区    (4)静态的注意事项;        A:在静态方法中没有this对象        B:静态只能访问静态(代码测试过)    (5)静态变量和成员变量的区别        A:所属不同            静态变量:属于类,类变量            成员变量:属于对象,对象变量,实例变量        B:内存位置不同            静态变量:方法区的静态区            成员变量:堆内存        C:生命周期不同            静态变量:静态变量是随着类的加载而加载,随着类的消失而消失            成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失        D:调用不同            静态变量:可以通过对象名调用,也可以通过类名调用            成员变量:只能通过对象名调用    (6)main方法是静态的        public:权限最大        static:不用创建对象调用        void:返回值给jvm没有意义        main:就是一个常见的名称。        String[] args:可以接收数据,提供程序的灵活性            格式:java MainDemo hello world java                  java MainDemo 10 20 30

static的引入

/*    定义一个人类        姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。    但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。    一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间,    我就觉得有点浪费了。怎么办呢?         针对多个对象有共同的这样的成员变量值的时候,        Java就提高了一个关键字来修饰:static。*/class Person {    //姓名    String name;    //年龄    int age;    //国籍    //String country;    static String country;        public Person(){}        public Person(String name,int age) {        this.name = name;        this.age = age;    }        public Person(String name,int age,String country) {        this.name = name;        this.age = age;        this.country = country;    }        public void show() {        System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);    }}class PersonDemo {    public static void main(String[] args) {        //创建对象1        Person p1 = new Person("邓丽君",16,"中国");        p1.show();                //创建对象2        //Person p2 = new Person("杨幂",22,"中国");        //p2.show();        Person p2 = new Person("杨幂",22);        p2.show();                //创建对象3        //Person p3 = new Person("凤姐",20,"中国");        //p3.show();        Person p3 = new Person("凤姐",20);        p3.show();                p3.country = "美国";//其他对象里的国籍也会变成“美国”        p3.show();                p1.show();        p2.show();    }}

static特点

/*    static的特点:(它可以修饰成员变量,还可以修饰成员方法)        A:随着类的加载而加载            回想main方法。        B:优先于对象存在        C:被类的所有对象共享            举例:咱们班级的学生应该共用同一个班级编号。            其实这个特点也是在告诉我们什么时候使用静态?                如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。            举例:                饮水机(用静态修饰)                水杯(不能用静态修饰)        D:可以通过类名调用            其实它本身也可以通过对象名调用。            推荐使用类名调用。                        因为:静态修饰的内容一般我们称其为:与类相关的,类成员*/class Student {    //非静态变量    int num = 10;        //静态变量    static int num2 = 20;}class StudentDemo {    public static void main(String[] args) {        Student s = new Student();        System.out.println(s.num);                System.out.println(Student.num2);//推荐类名调用        System.out.println(s.num2);    }}

static内存图解:

 

 

 static注意事项;

/*    static关键字注意事项        A:在静态方法中是没有this关键字的            如何理解呢?                静态是随着类的加载而加载,this是随着对象的创建而存在。                静态比对象先存在。先存在的,不能访问后面进来的。        B:静态方法只能访问静态的成员变量和静态的成员方法                静态方法:                    成员变量:只能访问静态变量                    成员方法:只能访问静态成员方法                非静态方法:                    成员变量:可以是静态的,也可以是非静态的                    成员方法:可是是静态的成员方法,也可以是非静态的成员方法。            简单记:                静态只能访问静态。*/class Teacher {    public int num = 10;    public static int num2 = 20;        public void show() {        System.out.println(num); //隐含的告诉你访问的是成员变量        System.out.println(this.num); //明确的告诉你访问的是成员变量        System.out.println(num2);                //function();        //function2();    }        public static void method() {                //System.out.println(num);//无法从静态上下文中引用非静态 变量 num        System.out.println(num2);                //无法从静态上下文中引用非静态 方法 function()        //function();        function2();    }        public void function() {        }        public static void function2() {        }}class TeacherDemo {    public static void main(String[] args) {        //创建对象        Teacher t = new Teacher();        t.show();        System.out.println("------------");        t.method();    }}

main方法的格式

/*    main方法的格式讲解:        public static void main(String[] args) {...}                public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。        static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。        void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。        main:是一个常见的方法入口。我见过的语言都是以main作为入口。        String[] args:这是一个字符串数组。值去哪里了?            这个东西到底有什么用啊?怎么给值啊?                这个东西早期是为了接收键盘录入的数据的。                格式是:                    java MainDemo hello world java*/class MainDemo {    public static void main(String[] args) {        //System.out.println(args); //[Ljava.lang.String;@175078b        //System.out.println(args.length); //0        //System.out.println(args[0]); //ArrayIndexOutOfBoundsException                //接收数据后        System.out.println(args);         System.out.println(args.length);         //System.out.println(args[0]);         for(int x=0; x

运行结果:

 

转载于:https://www.cnblogs.com/baiyangyuanzi/p/6808085.html

你可能感兴趣的文章
【sas notes】sas9.2安装
查看>>
jsp页面修改后保存无反映,后台也没有执行到代码。
查看>>
Java 编程下泛型的内部原理
查看>>
倒排索引 - doudoubluesky的日志 - 网易博客
查看>>
Probe how does your PGA consume
查看>>
留言板历史
查看>>
运行.bat批处理,CMD窗口隐藏,并制作为EXE文件
查看>>
zoj 1642 Match for Bonus(动态规划)
查看>>
20130414_怎样让博客园首页只显示文章标题与摘要
查看>>
关于LittleSis网站数据API的简单整理
查看>>
[转]提升6种心理商数 多角度展现个人魅力
查看>>
HDU 1893 Sibonacci Numbers(斐波那契)
查看>>
tempdb相关文章
查看>>
带包头路由协议的创建过程(转帖)
查看>>
Android 左右滑屏效果
查看>>
类方法代码重构-寻找坏味道
查看>>
析构函数构造函数CPerson派生出CEmployee类
查看>>
安装文件在Ubuntu12.04上部署CloudFoundry-ng (一) dea_ng和warden的部署
查看>>
SkinSharp For C# .Net 2005/2008/2010 使用帮助
查看>>
华夏工程dom4j (2) 编辑
查看>>