面向对象02

作者: 丫甘九 | 来源:发表于2018-11-09 21:44 被阅读36次

    成员变量和局部变量的区别

    1、在类中的位置不同
    • 成员变量 类中方法外
    • 局部变量 方法内或者方法声明上
    2、在内存中的位置不同
    • 成员变量 堆内存
    • 局部变量 栈内存
      (局部变量:在方法定义中或者方法声明上的变量都称为局部变量)

    注:
    java程序为了提高程序的效率,就对数据进行了不同空间的分配,具体的是划分了如下几个空间
    栈:存放的是局部变量
    堆:存放的是所有new出来的东西
    (堆内存的特点:
    A 每一个new出来的对象都有地址值
    B 每个变量都有默认值
    byte int short long 0
    float double 0.0
    char \u000
    boolean true false
    引用类型 null
    C 使用完毕就变成了垃圾,但不会立即回收,会在垃圾回收器空闲的时候回收 )
    方法区:专门存放方法的地方
    本地方法区(和系统有关):
    寄存器:(CPU使用)

    QQ图片20181109191131.png
    3、生命周期不同
    • 成员变量 随着对象的存在而存在,随着对象的消失而消失
    • 局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
    4、初始值不同
    • 成员变量 有默认的初始值
    • 局部变量 没有默认的初始值,只能先定义,赋值才能使用
    package mianxiangduixaing02;
    /*成员变量和局部变量的区别
    A 在类中的位置不同
    
       成员变量 类中方法外
       局部变量 方法内或者方法声明上
    
    B 在内存中的位置不同
    
       成员变量 堆内存
       局部变量 栈内存
       
    C 生命周期不同
    
       成员变量 随着对象的存在而存在,随着对象的消失而消失
       局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
    
    D 初始值不同
    
       成员变量 有默认的初始值
       局部变量 没有默认的初始值,只能先定义,赋值才能使用
    */
    public class Variable {
        //成员变量
        int num = 10;
        public void show(){
            //局部变量
            int num2=20;
        }
    }
    
    
    package mianxiangduixaing02;
    
    public class variabledemo {
    
        //不同方法中是不能访问另一个方法内的变量
    
        public static void main(String[] args){
            Variable v = new Variable();
            System.out.println(v.num);//访问成员变量
    
        }
    }
    
             结果为10
    
    public static void main(String[] args){
            Variable v = new Variable();
            System.out.println(v.num2);//访问局部变量error
            //只能访问成员变量,访问局部变量会报错
    }
    }
    
    public class Variable {
        //成员变量
        int num;//不给num赋值
        public void show(){
            //局部变量
            //int num2;  不给num2赋值,就没有默认初始值
            int num2 = 20;
            System.out.println(num2);
    
        }
    }
    
    public static void main(String[] args){
            Variable v = new Variable();
            System.out.println(v.num);//访问成员变量
             v.show();//访问show方法
    }
    }
    结果为10、20
    

    方法的形式参数是类名的时候如何调用

    什么是形式参数,什么是实际参数???
    • 形式参数:就是在定义函数或过程的时候命名的参数。通俗讲就是一个记号。
    • 实际参数:就是在执行时,调用函数或过程时,传递给函数或过程的参数。通俗讲就是实际值。
    • 参数嘛,就是一个可变量,它随着使用者的不同而发生变化。举个例子,在中学的时候学过sin(x)函数,这里的x就是形式参数,当你需要求1的正弦值时,你会使用sin(1),这里的1就是实际参数。
    • 形参和实参间的关系:两者是在调用的时候进行结合的,通常实参会将取值
    什么是基本类型,什么是引用类型???

    java中的数据类型分为两大类:基本数据类型和引用数据类型

    基本数据类型,包括数值型,字符型和布尔型。

    • 数值型:1)整型:byte 1个字节;short 2个字节;int 4个字节;long 8个字节。

    • 浮点型:float 4个字节;double
      8个字节;可以采用十进制和十六进制两种表示方式,其中十六进制表示方法只能采用科学计数法,例如:0x1.2p3,表示的是的是1乘以16加上2乘以16的-1次方的和乘以2的三次方;浮点型的默认类型为DOUBLE型,如果声明float型浮点数,要在数值后面加上f或F,例如:float
      f1 = 3.14F;否则会报精度错误。

    • 字符型:char 采用unicod的16位编码方式进行编码。

    • 布尔型:true,false;

    引用数据类型:类、接口类型、数组类型、枚举类型、注解类型;

    基本数据类型和引用数据类型的区别主要在存储方式上:

    • 基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上;

    • 引用数据类型在被床架时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。

    形式参数的问题
    • 基本类型:形式参数的改变不影响实际参数
    • 引用类型:形式参数的改变直接影响实际参数

    例1:形式参数是基本类型时

    package mianxiangduixaing02;
    
    public class xingshicanshu{
        public int sum(int a,int b)//形式参数,参数是基本类型
        {
        return a+b; 
        }
    
    }
    
    package mianxiangduixaing02;
    
    public class xingshicanshudemo {
        public static void main(String[] args) {
            xingshicanshu x = new xingshicanshu();
            //x.sum(10, 20); 无结果,会报错,不能直接调用
                    //为什么不能直接调用??
            int result = x.sum(10, 20);
            System.out.println("result:"+result);
            
        }
    
    }
    
          结果为30
    
    

    例2:形式参数是引用类型时

    package mianxiangduixaing02;
    
    public class student {
    public void show() {
        System.out.println("我爱学习");
    }
    }
    
    package mianxiangduixaing02;
    
    public class studentdemo {
    //如果看到一个方法的形式参数是一个类类型(引用类型),这里其实需要的就是该类的对象
             public void method(student s)//形式参数是引用类型
      {//调用的时候,把main方法中的地址传递到了这里       student s = new student()
    
             s.show();
    }
    }
    
    package mianxiangduixaing02;
    
    public class test {
    public static void main(String[] args) {
        //形式参数是引用类型时的调用
        //需求:调用studentdemo类中的method方法
        studentdemo sd = new studentdemo();
        //创建学生对象
            student s = new student();
        sd.method(s);//把s的地址值给到了这里
        
    }
    }
    
                     结果为“我爱学习”
    

    匿名对象的概述和应用

    匿名对像:

    就是没有名字的对象(是对象的一种简化表达形式)

    匿名对像的俩种使用情况:

    对象调用方法仅仅是一次的时候
    作为实际参数传参的时候

    package mianxiangduixaing02;
    
    public class test {
    public static void main(String[] args) {
        //形式参数是引用类型时的调用
        //需求:调用studentdemo类中的method方法
        studentdemo sd = new studentdemo();
        //创建学生对象
            student s = new student();
        sd.method(s);//把s的地址值给到了这里
        //匿名对像
        new student();//只是创建出一个对象,并没有调用,所以不出结果值
        //匿名对像调用方法
        new student().show();
        System.out.println("-----------------");
        //为什么仅仅只能调用一次?
        sd.method(s);
        sd.method(s);//这表示同一个对象调用了俩次方法
         new student().show();
         new student().show();//这表示重新创建了一个对象,所以多次调用的时候不适合
         
        
    }
    }
    
    结果为:
    我爱学习
    我爱学习
    -----------------
    我爱学习
    我爱学习
    我爱学习
    我爱学习
    
    
    匿名对像调用的好处是什么?

    A 匿名对像调用完毕后就是垃圾,可以被垃圾回收站回收
    B 匿名对像可以作为实际参数传递

    //匿名对像可以作为实际参数传递
         sd.method(new student());
         结果为:我爱学习
    

    private关键字的概述和特点

    封装概述
    • 是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式
    好处
    • 隐藏实现细节,提供公共访问方式
    • 提高了代码的复用性
    • 提高安全性
    封装原则
    • 将不需要对外提供的内容都隐藏起来
    • 把属性隐藏,提供公共方法对其访问
    private关键字
    • 是一个权限修饰符(只有自己可以访问)
    • 可以修饰成员(成员变量和成员方法)
    • 被private修饰的成员只能在本类中被访问
    private最常见的应用
    • 把成员变量用private修饰
    • 提供对应的getxxx()和ssetxxx()方法
      被private修饰后权限很小,只能自己访问
      案例
    package mianxiangduixaing02;
    
    public class privatedemo {
        //int num = 10;(1)
        private int num = 20;//(2)
        public void show(){
            System.out.println(num);
        }
    private void method(){
            System.out.println("method");
        }
        public void show2(){
            method();
        }
    
    }
    
    package mianxiangduixaing02;
    
    public class privatetest {
        public static void main(String[] args) {
            privatedemo pd = new privatedemo();
            //System.out.println(pd.num);(1)
            pd.show();//(2)
            pd.show2();
        }
    
    }
    num第一种定义为int类,测试类中可以直接访问num,得出结果10
    num第二种定义为private类,测试类中不可以直接访问,在privatedemo类中定义了一个公共的show方法,
    然后在此方法中输出被定义为private类的num,在测试类中创建的对象调用show方法,得出结果20,
    同理,被private修饰的方法也不能被直接调用,必须用同类中的一个公共的方法输出这个方法,
    然后在测试类中调用这个公共的方法,结果为method
    
    

    封装和private应用标准案例

    package mianxiangduixaing02;
    
    public 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 m){
            age = m;
        }
    }
    
    package mianxiangduixaing02;
    
    public class studenttest {
        public static void main(String[] args) {
            student s = new student();
            //System.out.println(s.Name+"---------"s.get);error
            System.out.println(s.getName()+"--------"+s.getAge());
            //给成员变量赋值
            //s.Name="李四";error
            //s.age="27";error
            //通过方法赋值
            s.setName("李四");
            s.setAge(27);
            System.out.println(s.getName()+"-------"+s.getAge());
        }
    
    }
    结果为:null--------0
           李四-------27
    getXxx()方法为获取,只能输出结果,setXxx()方法为赋值,可以修改前面定义好的数值,也可以直接用此方法赋值
    被private定义得无论是成员变量还是成员方法,都不可以被本类以外的类得到
    
    

    this关键字的概述和应用

    this关键字
    • this:代表所在类的对象引用,简单说,代表当前类的一个对象
    • 记住
      方法被哪个对象调用,this就代表那个对象
    什么时候使用this呢???
    • 局部变量隐藏成员变量
    • 其他用法见后面详解
      案例
    package mianxiangduixaing02;
    //java中起名字要见名知意,单独的n,a拿出来别人并不知道是什么意思
    public class student {
        private String name;
        private  int age;
        public String getName(){
            return name;
        }
        /*public void setName(String n){
            name= n;
        }
        */
        public void setName(String name){//name=李四
            //name= name;
            this.name=name;
        }
        //所以在这里将n改为name
      //但是变量的使用规则是就近原则,所以这个是有问题的,结果出来为null  0
        //这里的调用只能用对象名
        //这个对象如果存在,它应该代表的就是student类中的一个对象
        //那么谁能够代表当前的对象呢?java就提供了一个关键字   this
        //this.name=name;
        public int getAge(){
            return age;
        }
        /*public void setAge(int m){
            age = m;
        }
        */
        public void setAge(int age){
            //age = age;
            this.age=age;
        }
        //在这里将m改为age
        
    }
    
    package mianxiangduixaing02;
    
    public class studenttest {
        public static void main(String[] args) {
            student s = new student();
            //System.out.println(s.Name+"---------"s.get);error
            System.out.println(s.getName()+"--------"+s.getAge());
            //给成员变量赋值
            //s.Name="李四";error
            //s.age="27";error
            //通过方法赋值
            s.setName("李四");
            s.setAge(27);
            System.out.println(s.getName()+"-------"+s.getAge());
        }
    
    }
    结果为:null--------0
           李四-------27
    
    

    this关键字的内存图解

    package mianxiangduixaing02;
    
    public class student1 {
    private String name;
    private int 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;
    }
    }
    
    package mianxiangduixaing02;
    
    public class student1test {
        public static void main(String[] args) {
            student1 s1 = new student1();//创建第一个对象
            s1.setName("李美丽");
            s1.setAge(27);
            System.out.println(s1.getName()+"--------"+s1.getAge());
            student1 s2 = new student1();//创建第二个对象
            s2.setName("刘小花");
            s2.setAge(18);
            System.out.println(s2.getName()+"--------"+s2.getAge());
        }
    
    }
    
    
    QQ图片20181111210239.png
    注:首先,程序从main方法开始执行,创建第一个student1类的对象,然后对象调setName/setAge方法,程序走到student1类中的setName/setAge方法,将李美丽赋值给name(因为有形参,所以String name就相当于李美丽,this.name=String name=李美丽),然后程序走到类中方法外的成员变量name,当程序输出s1.getName()的时候,程序走到getName()方法,返回了name(此时的name就是刚才类中方法外的name),返回的name就输出了,结果为李美丽,其他同上

    构造方法的概述与格式

    构造方法作用概述
    • 给对象的数据进行初始化
    构造方法格式
    • 方法名与类名相同
    • 没有返回值类型,连void也没有(修饰符那一块没有任何东西)
    • 没有具体的返回值(不需要用return来做什么东西)
    构造方法的注意事项
    • 如果你不提供构造方法,系统会给出默认的构造方法
    • 如果你提供了构造方法,系统将不会再给出
    • 构造方法也是可以重载的

    构造方法的格式及作用案例

    package mianxiangduixaing02;
    
    public class construct {
        private String name;//null
        private int age;// 0 
        //系统自动给的初始值,所以构造方法的作用就是给成员变量赋默认值
        public construct(){//这就是构造方法
            System.out.println("这是一个构造方法");
        }
    
    }
    
    package mianxiangduixaing02;
    
    public class constructtest {
        public static void main(String[] args) {
            construct c = new construct();
            char[] s = null;
            System.out.println(s);//输出的是构造方法中的内容
        }
    
    }
    
    
    构造方法的重载及注意事项

    方法重载就是方法重写,构造方法重载就是将系统自带的构造方法重写
    我们一直在使用构造方法,但是我们却没有定义过,那么构造方法从哪来呢?

    • 构造方法的注意事项
    • A 如果我们没有给出构造方法,系统将会自动提供一个无参构造方法
    • B 如果我们给出了构造方法,系统将不会提供默认的构造方法
    • 注:如果这个时候,我们还想用无参构造方法,就必须自己定义,建议自己定义无参构造方法
    • 给成员赋值有俩种方法
    • A setXxx()方法
    • B 构造方法
      public class con
    package mianxiangduixaing02;
    struct {
        private String name;
        private int age; 
        public construct(){
            System.out.println("这是无参构造方法");
        }
        
        public construct(String name){
            System.out.println("这是带一个String类型的构造方法");
            this.name = name;
        }
        
        public construct(int age){
            System.out.println("这是带一个int类型的构造方法");
            this.age = age;
        }
        
        public construct(String name,int age){
            System.out.println("这是带一个String,int类型的构造方法");
            this.name = name;
            this.age = age;
        }
        public void show(){
            System.out.println(name+"-------"+age);
        }
    
    }
    
    package mianxiangduixaing02;
    
    public class constructtest {
        public static void main(String[] args) {
            //创建对象1
            construct c1 = new construct();
            c1.show();
            //创建对象2
            construct c2 = new construct("李美丽");
            c2.show();
            //创建对象3
            construct c3 = new construct(18);
            c3.show();
            //创建对象4
                    construct c4 = new construct("李美丽"+18);
                    c4.show();
        }
    }
    
    结果为:
    null-------0
    这是带一个String类型的构造方法
    李美丽-------0
    这是带一个int类型的构造方法
    null-------18
    这是带一个String类型的构造方法
    李美丽18-------0
    
    

    成员方法的分类及使用

    类的成员方法分类
    根据返回值
    • 有明确返回值类型
    • 返回void类型的方法(无返回值类型)
    根据形式参数
    • 无参方法
    • 带参方法
      类的组成:成员变量、构造方法、成员方法
    package mianxiangduixaing02;
    
    public class student2 {
        public String getString1(){//无参有返回值类型
            return  "hello1";
        }
        public void getString2(){//无参无返回值类型
            System.out.println("hello2");
        }
        public String getString3(String name){//带参有返回值类型
            return name;
        }
        public void getString4(String name){//带参无返回值类型
            System.out.println(name);
        }
        
    
    }
    
    package mianxiangduixaing02;
    
    public class student2test {
        public static void main(String[] args) {
            student2 s= new student2();
            //调用无参有返回值类型
            String result = s.getString1();
            System.out.println(result);
            //调用无参无返回值类型
            s.getString2();
            //调用带参有返回值类型
            String result2 = s.getString3("hello3");
            System.out.println(result2);
            //调用带参无返回值类型
             s.getString4("hello4");
            
        }
    
    }
    
    结果为:
    hello1
    hello2
    hello3
    hello4
    
    

    创建对象时做了哪些事情

    student s = new student();在内存中做了哪些事情?
    • 加载student class文件进内存
    • 在栈内存为s开辟内存空间
    • 在堆内存为学生对象开辟内存空间
    • 对学生对象的成员变量进行默认初始化
    • 对学生对象的成员变量进行显示初始化
    • 通过构造方法对学生对象的成员变量赋值
    • 学生对象初始化完毕,把对象地址赋值给s变量
      student 类案例及内存图解
    package mianxiangduixaing02;
    
    public class student3 {
        private String name = "李美丽";//原本默认初始值为null
        private int age = 27;//原本默认初始值为0
    //在这里操作者手动给了值,name和age就变成了李美丽27//显示初始化
        public student3(){//构造方法给成员变量赋值
            name = "李四";
            age = 30;
        }
                
    
    }
    
    package mianxiangduixaing02;
    
    public class student3test {
        public static void main(String[] args) {
            student3 s = new student3();
            
        }
    
    }
    结果:李四  30
    
    
    QQ图片20181112173254.png

    static关键字的引入

    static关键字
    可以修饰成员变量和成员方法
    static关键字的特点
    • 随着类的加载而加载
      (回想main方法,用static修饰的方法,如果class加载的时候没有加载main方法,我们使用的时候还能直接用么?不能,所以是随着类的加载而加载)
    • 优先于对象存在
      (对象是在new的时候才出现,而它在class文件加载的时候就已经出现了)
    • 被类的所有成员共享(这也是我们判断是否使用关键字的条件,代码如下)
    • 可以通过类名调用,其实她本身也可以通过对象名调用(推荐使用类名调用)
      静态修饰的内容我们一般称其为:与类相关的,类成员
      static:静态修饰成员变量(static怎么用),详细如下代码可见
    public 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="+name+"--------"+"age="+age+"-------"+"country="+country);
        }
    
    }
    
    package mianxiangduixaing02;
    
    public class persontest {
        public static void main(String[] args) {
            person p1 = new person("李美丽",16,"中国");
            p1.show();
            person p2 = new person("刘小花",18,"中国");
            p2.show();
            person p3 = new person("凤姐",27,"中国");
            p3.show();
            //三个人,名字和年龄都是不一样的,但是国籍都为中国,
            //每new一次都开辟一次内存空间,太浪费内存了,所以java就提供了一个关键字 static
            //用static修饰country
            System.out.println("------------------------------------------------");
            person p4 = new person("李美丽",16,"中国");
            p4.show();
            person p5 = new person("刘小花",18);
            p5.show();
            person p6 = new person("凤姐",27);
            p6.show();
            //在用static定义后,这里只给了p4国籍,其他俩个都没给
            //结果和上面一样,都有三个变量显示
            System.out.println("-----------------------------------------------");
            p6.country="美国";
            p6.show();
            p4.show();
            p5.show();
            //结果都为美国,因为这些对象共享同一个静态修饰的成员
                    System.out.println(person.country);   //通过类名调成员            
        }
    
    }
    
    结果为:
    name=李美丽--------age=16-------country=中国
    name=刘小花--------age=18-------country=中国
    name=凤姐--------age=27-------country=中国
    ------------------------------------------------
    name=李美丽--------age=16-------country=中国
    name=刘小花--------age=18-------country=中国
    name=凤姐--------age=27-------country=中国
    -----------------------------------------------
    name=凤姐--------age=27-------country=美国
    name=李美丽--------age=16-------country=美国
    name=刘小花--------age=18-------country=美国
    美国
    
    
    static关键字的注意事项
    • 在静态方法中是没有this关键字的
    • 静态方法只能访问静态的成员变量和静态的成员方法
      案例代码如下
    package mianxiangduixaing02;
    //static 关键字注意事项
    //A 在静态方法中是没有this关键字的  如何理解呢???
    //静态是随着类的加载而加载,this是随着对象的创建而存在
    //静态比对象先存在
    //B  静态方法只能访问静态的成员变量和静态的成员方法
    //静态方法
    //成员变量:只能访问静态的成员变量
    //成员方法:只能访问静态的成员方法
    //非静态方法
    //成员变量:可能是静态的,也可能是非静态的
    //成员方法:可能是静态
    public 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);//error,无法从静态上下文中引用非静态
            System.out.println(num2);
        }
        public void function(){
            
        }
        public static void function2(){
            
        }
    
    }
    
    
    package mianxiangduixaing02;
    
    public class Teachertest {
        public static void main(String[] args) {
            Teacher t = new Teacher();
            t.show();
            t.method();
        }
    
    }
    
    结果为:
    10
    10
    20
    20
    
    

    静态变量和成员变量的区别

    所属不同
    • 静态变量属于类,所以也称为类变量
    • 成员变量属于对象,所以也称为实例变量(对象变量)
    内存中的位置不同
    • 静态变量存储于方法区的静态区
    • 成员变量存储于堆内存
    内存出现的时间不同
    • 静态变量随着类的加载而加载,随着类的消失而消失
    • 成员变量随着对象的创建而存在,随着对象的消失而消失
    调用不同
    • 静态变量可以通过类名调用,也可以通过对象调用
    • 成员变量只能通过对象名调用

    相关文章

      网友评论

        本文标题:面向对象02

        本文链接:https://www.haomeiwen.com/subject/asnoxqtx.html