zoukankan      html  css  js  c++  java
  • Java基础教程——封装

    面向对象的三大特征

    • 封装:encapsulation
    • 继承:inheritance
    • 多态:polymorphism

    封装

    类是一个最基本的封装

    封装的好处:

    • 数据安全:保证数据安全
    • 方便调用:提供清晰的对外接口,方便外界调用
    • 降低耦合:类内部的实现可以修改,不影响其他类

    电脑主机就是一个封装的例子,内存等硬件封装在机箱中,对外提供显示器接口、电源接口、USB接口,加根内存条不影响外界的使用。

    良好的封装:尽可能限制类和成员的可访问性 。

    对于代码而言:对象的状态信息被隐藏在内部,外界无法直接访问,必须通过该类对外提供的方法访问。

    可以防止外界进行不合理的赋值(如年龄赋值为负数),方便对属性值的控制

    可参见“共享单车”或“公地悲剧”:

    属性

    1.成员变量设为private;

    2.提供public的get/set方法作为访问器。

    早年有书把field翻译为“属性”,现在field一般翻译为“成员变量”。成员变量不一定有方法器。

    例:妖孽类有两个属性:name和species。

    class 妖孽 {
    	private String name;
    	private String species;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getSpecies() {
    		return species;
    	}
    	public void setSpecies(String species) {
    		this.species = species;
    	}
    }
    

    Eclipse中自动生成属性的快捷键:

    代码中点击右键(快捷键Ctrl+Alt+S)
    ->Source
    ->Generate Getters and Setters...
    ->全选(或选择需要生成的字段/方法)


    访问修饰符

    (暂时可以不必全部理解,只需要关注private)

    访问修饰符 自身 同包 同包 不同包 不同包
    继承 不继承 继承 不继承
    public 大家用
    protected 子类用,同包用 X
    (default) 同包用(不写) X X
    private 自己用 X X X X

    成员变量·局部变量

    成员变量:类里面定义的变量

    局部变量:(1)方法中定义的变量;(2)复合语句中定义的变量for(int n : arr){...}

    public class 变量 {
    	int 成员变量 = 1;
    	void m() {
    		int 局部变量 = 2;
    		System.out.println("m():" + 局部变量 + "," + 成员变量);
    	}
    	void m2() {
    		int 局部变量 = 3;
    		System.out.println("m2():" + 局部变量 + "," + 成员变量);
    		for (int i = 0; i < 10; i++) {
    			System.out.print(i + " ");
    		}
    	}
    	public static void main(String[] args) {
    		变量 t = new 变量();
    		t.m();
    		t.m2();
    	}
    }
    

    成员变量和局部变量不同之处:

    成员变量 局部变量
    定义位置 方法内存 方法内部,甚至语句中
    作用范围 整个类都可以用 方法中可用,甚至语句范围内可用
    生命周期 方法调用时诞生,方法结束消失 对象创建诞生,对象被回收消失
    默认值 有默认值,规则和数组一样 无默认值,必须手动赋值
    内存位置 栈(方法调用入栈,结束出栈)

    方法(method)

    方法,是类或对象行为的抽象。从功能上,方法类似于函数。

    Java里的方法不能独立存在,必须写在类中。

    传参:值传递

    Java只有一种参数传递方式——值传递。

    所谓值传递,就是将“实际参数”的副本传入方法,“实际参数”本身不受任何影响。
    如经典的交换方法swap:

    public class PassParameter {
    	static void swap(int a, int b) {
    		int temp = a;
    		a = b;
    		b = temp;
    		System.out.println("内部:a = " + a + ", b = " + b);
    	}
    	public static void main(String[] args) {
    		int x = 100, y = 200;
    		System.out.println("交换前:x = " + x + ", y = " + y);
    		swap(x, y);
    		// 并没有交换成功
    		System.out.println("交换后:x = " + x + ", y = " + y);
    	}
    }
    

    ↑swap得到的参数,只是实参x、y的复制品,实际上出现了4个变量。
    运行结果:

    交换前:x = 100, y = 200
    内部:a = 200, b = 100
    交换后:x = 100, y = 200
    

    ​ 要想交换两数的值,可以将其封装到类中,类是引用类型,但传参的时候还是“值传递”。

    ​ 不过,类变量中存放的其实是对象的引用,方法中对类变量进行修改,改变的不是变量的内存,而是其引用的实例对象的内容。

    public class PassParameter2 {
    	static void swap(MyData data) {
    		int temp = data.a;
    		data.a = data.b;
    		data.b = temp;
    	}
    	public static void main(String[] args) {
    		MyData md = new MyData();
    		md.a = 100;
    		md.b = 200;
    		swap(md);
    		System.out.println("md.a = " + md.a + ", md.b = " + md.b);
    	}
    }
    class MyData {
    	int a;
    	int b;
    }
    

    注意,企图在函数中,对"类类型"的对象直接赋值是不行的,只能对其中的变量进行赋值。
    所以不要意图通过方法调用对字符串进行赋值。

    例如:

    public class TestMethod {
    	void changeData(MyData2 md) {
    		md = new MyData2();
    	}
    	void changeStr(String s) {
    		s = "新";
    	}
    	public static void main(String[] args) {
    		TestMethod t = new TestMethod();
    		MyData2 md2 = null;
    		// 方法中对类对象赋值
    		t.changeData(md2);
    		System.out.println("md = " + md2);
    		// 方法中对字符串赋值
    		String s = "旧";
    		t.changeStr(s);
    		System.out.println(s);
    	}
    }
    class MyData2 {
    }
    

    运行结果:

    md = null
    旧
    

    构造方法

    构造方法也叫构造器,Constructor。

    • 作用:初始化对象,通常是为成员变量赋初始值。

    • 特点:1.没有返回值;2.方法名必须和类名一致。

    其实构造方法的返回值是隐式的,就是当前类的对象。
    new一个对象,实际上是调用其构造方法。
    对象在构造方法调用前已经产生,但是需要通过构造方法返回。

    public class 类和对象 {
    	public static void main(String[] args) {
    		Tiger c = new Tiger();
    	}
    }
    class Tiger {
    	public Tiger() {
    		System.out.println("---构造方法---");
    	}
    }
    

    运行结果:

    ---构造方法---


    无参构造方法:

    • 如果不手写构造方法,系统默认提供一个“无参构造方法”。

    • 如果手写构造方法,系统不再提供无参构造方法。


    构造方法自动生成:

    自动生成的构造方法中往往会有一句super(),表示调用父类的无参构造方法,删掉也会调用。

    class Tiger {
    	private String name;
    	public Tiger(String name) {
    		super();// 此代码可以不要,表示调用父类构造方法
    		// 成员变量和参数同名,根据就近原则,name使用参数,加this表示使用成员变量
    		this.name = name;
    	}
    }
    

    重载·overload

    1.方法名相同
    2.参数列表不同:
    a)参数类型相同,个数不同
    b)参数个数相同,类型不同
    3.重载不管修饰符、返回类型等(方法调用可以不管返回值)

    public class TestOverload {
    	static void m(int a, int b) {
    		System.out.println("m1");
    	}
    	static void m(int a, double b) {
    		System.out.println("m2");
    	}
    	public static void main(String[] args) {
    		m(1, 2);
    		m(1, 2.0);
    	}
    }
    

    静态·static

    static可以用来修饰{类、成员变量、方法、代码块},表示这些成分属于“类本身”而不是“实例”。

    静态变量

    成员变量分为:
    |-类变量(静态)
    |-实例变量

    实例可以有多个,每个实例可以有自己的数据;
    类只有一个,static修饰的变量属于类,也只有一份,多个对象可以共享。

    示例:数猫咪

    public class Test静态变量 {
    	public static void main(String[] args) {
    		Cat c1 = null;
    		for (int i = 1; i <= 100; i++) {
    			c1 = new Cat();
    			c1.count++;
    			c1.countStatic++;
    		}
    		System.out.println(c1.count);
    		System.out.println(c1.countStatic);
    		Cat.countStatic++;// 静态变量可以直接通过类名调用
    		System.out.println(c1.countStatic);
    	}
    }
    class Cat {
    	static int countStatic = 1;
    	int count = 1;
    }
    

    静态方法

    静态方法不属于对象,属于类。
    静态分不需要new(实例化对象)就可以使用。

    最著名的静态方法就是main方法。

    静态方法的使用方式:类名.静态方法名(参数列表);

    Array.sort(...)就是一个静态方法,没有new一个Arrays类出来,就可以使用之。

    package ah;
    public class Test静态方法 {
    	public static void main(String[] args) {
    		Dog.method静态方法();// 其他类中:类名调用
    		// 非静态方法(普通方法):new对象调用
    		Dog _dog = new Dog();
    		_dog.method普通方法();
    	}
    }
    class Dog {
    	void method普通方法() {
    		System.out.println("Dog:method普通方法");
    	}
    	static void method静态方法() {
    		System.out.println("Dog:method静态方法");
    	}
    }
    

    如果是在当前类中调用,类名可以省略。

    public class Test静态方法2 {
    	void method普通方法() {
    		System.out.println("method普通方法");
    	}
    	static void method静态方法() {
    		System.out.println("method静态方法");
    	}
    	// -----------------------------
    	public static void main(String[] args) {
    		Test静态方法2.method静态方法();// 本类中:类名调用
    		method静态方法();// 本类:直接调用
    		// 即自己的非静态方法,也必须new
    		Test静态方法2 _self = new Test静态方法2();
    		_self.method普通方法();
    	}
    }
    

    静态代码块

    普通代码块:类被创建(new)的时候执行,比构造方法还早。
    静态代码块:类被使用的时候执行,比普通代码块还早。
    |--当第一次使用本类时,静态代码块执行,且之后不会再执行。

    public class Test静态代码块 {
    	public static void main(String[] args) {
    		Tiger _t = new Tiger();
    	}
    }
    class Tiger {
    	public Tiger() {
    		System.out.println("构造方法");
    	}
    	{
    		System.out.println("普通代码块");
    	}
    	static {
    		System.out.println("静态代码块");
    	}
    }
    

    输出结果:

    静态代码块
    普通代码块
    构造方法

    静态代码块的典型用途:一次性对静态成员变量进行赋值。
    如:

    public class Test静态代码块 {
    	public static void main(String[] args) {
    		System.out.println(Driver.os);
    	}
    }
    class Driver {
    	static String os;
    	static {
    		if ("Windows 10".equals(System.getProperty("os.name"))) {
    			os = "WinDriver";
    		} else {
    			os = "Driver";
    		}
    	}
    }
    
  • 相关阅读:
    垃圾回收app冲击(一)
    本篇看似是一篇拍马屁的博客!但是真情实感!
    搜索建议
    冲击团队项目需求分析
    疫情分析冲击(五)
    疫情分析冲击(四)
    疫情分析冲击(三)
    疫情分析冲击(二)
    垃圾分类网站
    Android学习——singleInstance
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11179155.html
Copyright © 2011-2022 走看看