• Java基础之:OOP——类变量与类方法


    Java基础之:OOP——类变量与类方法

    类变量与类方法,我们习惯也将其称为静态变量与静态方法。

     

    类变量/静态变量

    通过一个实际案例来了解,为什么需要使用静态变量。

    引入案例

    声明一个学生类,每创建一个学生对象,统计学生的人数。

    public class Test{
        public static void main(String[] args){
            
            int count = 0; //局部变量,累积计数
            Student stu1 = new Student("小范");
            count ++;
            Student stu2 = new Student("小黄");
            count ++;
            Student stu3 = new Student("小雨");
            count ++;
            
            System.out.println("目前学生人数有:" + count);
        }
        
    }
    
    class Student{
        private String name;
        
        public Student(String name){
            this.name = name;
        }
        
    }

    通过这个案例我们可以看到,count作为一个局部变量,独立于Student外,当然也和创建的学生对象没有任何关联。以后在访问count的时候会很麻烦,在Student类中访问count也很麻烦。

    解决方案:将count设置为类变量/静态变量

     

    解决案例

    package static_args_methods.args;
    
    public class Static_args {
    
    	public static void main(String[] args) {
    		Student student = new Student("小范");
    		System.out.println(student.showFee());	// 100
    		
    		Student student2 = new Student("小黄");
    		System.out.println(student2.showFee());	//200
    //		System.out.println(Student.fee); //私有属性,无法访问
    		System.out.println(Student.count); //2
    		
    	}
    }
    
    class Student{
    	private String name;
    	//static + 访问修饰符 + 类型 + 属性名
    	static private double fee; //学费
    	
    	static Blackboard bb; //黑板
    	
    	//访问修饰符 + static + 类型 + 属性名 (推荐)
    	public static int count; //人数
    	
    	public Student(String name) {
    		super();
    		this.name = name;
    		fee += 100;	//每个学生交100学费
    		count += 1;
    	}
    	
    	public double showFee(){
    		return fee;
    	}
    }
    
    class Blackboard{
    	
    }

    案例说明

     

    由此案例,引出类变量/静态变量的概念及使用。

    概念

    类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。

    定义语法

    访问修饰符 static 数据类型 变量名; [推荐]

    static 访问修饰符 数据类型 变量名;

    访问方法

    类名.类变量名 [推荐]

    或者 对象名.类变量名 【静态变量的访问修饰符的访问权限和范围 和 普通属性是一样的。】

    使用说明

    1. 当需要一个类的所有对象都可以共用一个属性时,就可以将此属性设置为静态属性。例如,Student中的count属性。

    2. 被静态static修饰过的属性,在类加载时就会被生成,然后初始化。

    3. 建议使用“类名.属性名” 的方式访问静态属性,因为静态属性(类变量)的生命周期是随类的加载开始,随着类消亡而销毁。在类加载的时候,并没有对象被创建,此时也可以使用类变量。

    4. 类变量是所有对象共享使用的,而普通变量是每个对象都独有的。

    5. 类变量的使用,访问权限也是由访问修饰符修饰的。例如:Student 的类变量 count 是 private 修饰的,那么在 Static_args 类中也不能通过 Student.count 来访问。

     

    类方法/静态方法

    类方法也叫静态方法 。

     

    形式如下:

    访问修饰符 static 数据返回类型 方法名() { } 【推荐】

    static 访问修饰符 数据返回类型 方法名() { }

     

    类方法的调用:

    使用方式: 类名.类方法名 或者 对象名.类方法名 【前提是 满足访问修饰符的访问权限和范围】

    使用说明

    1. 类方法与普通方法都是在类加载时就加载了,将其结构信息放在方法区中。

    2. 类方法中没有this关键字,也不能使用super关键字。因为类方法在类加载时就可以调用,此时还没有对象被生成。而this与super都是代表对象的关键字。

    3. 类方法/静态方法 只能访问静态属性或者调用其他静态方法,不可以使用成员属性与成员方法。因为在类方法被加载时,成员属性与成员方法都还没有被加载出来,不能使用。【前提是 满足访问修饰符的访问权限和范围】

    4. 而在成员方法(普通方法)中可以使用所有的静态方法与静态属性。【前提是 满足访问修饰符的访问权限和范围】

    5. 但不要误理解为,静态方法中使用的任何属性或方法都必须是静态的。也可以在静态方法中声明普通属性来使用。

    说明案例

    public class StaticMethodDetail {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		//类方法可以通过类名调用,也可以通过对象名调用
    		new DD().hi();
    		DD.hi();
    	}
    
    }
    
    
    class EE {
    	public String name = "EE";
    }
    
    class DD extends EE {
    	/*
    	 * 类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区 :类方法中无this的参数,普通方法中隐含着this的参数
    	 * 类方法中,不能使用this ,普通方法可以使用this
    
    	 */
    	
    	private int num = 200;
    	private static String name = "老王";
    	public static void hi() {
    		//System.out.println(this.num);
    	}
    	
    	//类方法中不允许使用和对象有关的关键字,比如this和super
    	public static void ok() {
    		//System.out.println(this.num);
    		//System.out.println(super.name);
    	}
    	//类方法(静态方法)中 只能访问 静态变量 或静态方法
    	
    	public void m1() { 
    		
    	}
    	
    	public static void hello() {
    		ok();
    		//m1();
    		System.out.println(name);
    	}
    	//普通成员方法(非静态方法),既可以访问 普通变量(方法),也可以访问静态变量(方法)
    	public void m2() {
    		ok();
    		m1();
    		System.out.println(name);
    		System.out.println(num);
    	}
    }
    

     

    简单案例

    package static_args_methods.methods;
    
    public class Static_methods {
    
    	public static void main(String[] args) {
    		Person person = new Person("小黄", 2000);
    		Person person2 = new Person("小范", 2500);
    		
    		//可以使用类名调用,也可以使用对象调用
    		System.out.println(Person.show());	//建议
    		System.out.println(person2.show());	
    	}
    
    }
    
    class Person{
    	private String name;
    	private double salary; //工资
    	private static double totalSalary; //总工资
    	
    	public Person(String name, double salary) {
    		super();
    		this.name = name;
    		this.salary = salary;
    		sumSalary(salary);
    	}
    	
    	//静态方法
    	public static void sumSalary(double salary) {
    		totalSalary += salary;
    	}
    	
    	//返回总工资(静态方法里只能使用静态属性与方法)
    	public static double show() {
    //		salary = 100; //Cannot make a static reference to the non-static field salary
    //		this.totalSalary = 100; //在静态方法中没有this指针,也不可以使用super
    		return Person.totalSalary;
    	}
    }
    

     

    理解main

    由于java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的,该方法接收一个String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数。

    简单案例

    public class TestMain
    {
    
    	private String name = "jack";
    	private static int num = 600;
    
    	//1.main方法时JVM调用,因此 public static
    	//2. String[] args 是运行程序时,可以输入的
    	//3. 比如 java TestMain tom jack smith
    	public static void main(String[] args) {
    		
    		for(int i= 0 ;  i < args.length;i++) {
    			System.out.println(args[i]);
    		}
    
    		//m1();
    		m2();
    		System.out.println(num);
    
    		//如果我们就是要再 main调用非静态的成员,需要先创建对象,再调用..
    		TestMain tm = new TestMain();
    		tm.m1();
    	}
    
    	public void m1() {
    		
    	}
    
    	public static void m2() {
    		
    	}
    }
    

      

     

  • 相关阅读:
    asp.net连接SQL server,SQLLite,Oracle,Access数据库
    c#中RadioButtonList选中后不整体刷新页面保持选中状态
    c#中onclick事件请求的两种区别
    java中从实体类中取值会忽略的的问题
    Groovy自定义函数实现时间表达式解析
    广度优先搜索、狄克丝特拉算法
    创建型模式
    数组、链表、散列表、图、树、队列、栈
    nginx.conf
    Nginx笔记一
  • 原文地址:https://www.cnblogs.com/SongHai/p/14128212.html
Copyright © 2020-2023  润新知