Java面向对象-封装

面向对象程序有以下特点:

  • 封装性
  • 继承性
  • 多态性

封装

封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体是类,第三方只需调用即可使用,无需关注内部的细节

继承

如有class A里面有一个add方法,现编写了一个class B 新增的class B可以使用extends 来继承class A并可直接使用class A中的add方法

多态

如创建了一个螺丝类,这个螺丝类中有两个属性:粗、细,然后又创建了两个类继承了螺丝类,他们两个都有各自的属性,长、短,综上所述,一个螺丝类衍生出不同的子类,子类继承父类特征的同时,也具备了自己的特征,并且能够实现不同的效果,这就是多态化结构。

Demo01PrintArray.java

import java.util.Arrays;

/*
 * 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节。
 * 面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事儿。
 */
public class Demo01PrintArray {

    public static void main(String[] args) {
        int[] array = { 10, 20, 30, 40, 50, 60 };

        // 要求打印格式为:[10, 20, 30, 40, 50]
        // 使用面向过程,每一个步骤细节都要亲力亲为。
        System.out.print("[");
        for (int i = 0; i < array.length; i++) {
            if (i == array.length - 1) { // 如果是最后一个元素
                System.out.println(array[i] + "]");
            } else { // 如果不是最后一个元素
                System.out.print(array[i] + ", ");
            }
        }
        System.out.println("==============");

        // 使用面向对象
        // 找一个JDK给我们提供好的Arrays类,
        // 其中有一个toString方法,直接就能把数组变成想要的格式的字符串
        System.out.println(Arrays.toString(array));
    }
}

类与对象

环顾周围,你会发现很多对象,比如桌子,椅子,同学,老师等。桌椅属于办公用品,师生都是人类。那么什么是 类呢?什么是对象呢?

什么是类?

  • 类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该 类事物。

现实中,描述一类事物:

  • 属性:就是该事物的状态信息。
  • 行为:就是该事物能够做什么。

举例:小猫。

属性:名字、体重、年龄、颜色。 行为:走、跑、叫。

什么是对象?

  • 对象:是一类事物的具体体现。对象是类的一个实例(对象并不是找个女朋友),必然具备该类事物的属性 和行为。

现实中,一类事物的一个实例:一只小猫。
举例:xxx家的那一只小猫。

属性:tom、5kg、2 years、yellow。 行为:溜墙根走、蹦跶的跑、喵喵叫

类与对象的关系

  • 类是对一类事物的描述,是抽象的。
  • 对象是一类事物的实例,是具体的。
  • 类是对象的模板,对象是类的实体。

成员变量与成员对象的使用

 * 成员变量赋值:
 * 		A:setXxx()方法
 * 		B:带参构造方法	

学生类的使用,示例代码:

Student.java

/*
 * 类的定义:
 * 		类是用来描述现实世界的事物的
 * 
 * 事物:
 * 		属性	事物的描述信息
 * 		行为	事物能够做什么
 * 
 * 类是如何和事物进行对应的呢?
 * 		类:
 * 			成员变量
 * 			成员方法
 * 
 * 需求:写一个学生类
 * 
 * 学生事物:
 * 		属性:姓名,年龄...
 * 		行为:学习,吃饭...
 * 
 * 学生类:
 * 		成员变量(属性):姓名,年龄
 * 		成员方法(行为):学习,吃饭
 *
 * 成员变量(属性):和我们前面学习过的变量的定义是一样的。
 * 		位置不同:类中,方法外
 * 		初始化值:不需要给初始化值
 * 成员方法(行为):和我们前面学习过的方法的定义是一样的。
 * 		需要去掉static关键字
 */
public class Student {
	// 成员变量
	// 姓名
	String name;
	// 年龄
	int age;
	
	// 成员方法
	// 学习的方法
	public void study() {
		System.out.println("好好学习,天天向上");
	}
	
	//吃饭的方法
	public void eat() {
		System.out.println("学习饿了要吃饭");
	}
}

StudentDemo.java

/*
* 通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。
* 
* 1.导包:也就是指出需要使用的类,在什么位置。
* import 包名称.类名称;
* import cn.itcast.day06.demo01.Student;
* 对于和当前类属于同一个包的情况,可以省略导包语句不写;
* java.lang包下的类也可以省略不用import【一部分jdk官方自带的类在这下面】;
* 
* 2.创建对象,格式:
* 类名称 对象名 = new 类名称();
* Student stu = new Student();
* 
* 3.使用,分为两种情况:
* 使用成员变量:对象名.成员变量名
* 使用成员方法:对象名.成员方法名(参数)
* (也就是,想用谁,就用对象名点儿谁)
* 
* 注意事项:
* 如果成员变量没有进行赋值,那么将会有一个默认值,规则和数组一样。
*/
import Demo.Student; // 在同一个包下不进行导入也可以使用

public class StudentDemo {
	public static void main(String[] args) {
		// 格式:类名 对象名 = new 类名();
		Student s = new Student(); // 在同一个包下面无需import就可使用到上面的Student类
		// System.out.println("s:"+s); // com.itheima_02.Student@193c0cf
		
		// 直接输出成员变量值
		System.out.println("姓名:"+s.name); // null
		System.out.println("年龄:"+s.age); // 0
		System.out.println("----------");
		
		// 给成员变量赋值
		s.name = "张三";
		s.age = 28;
		
		// 再次输出成员变量的值
		System.out.println("姓名:"+s.name); // 张三
		System.out.println("年龄:"+s.age); // 28
		System.out.println("----------");
		
		// 调用成员方法
		s.study();
		s.eat();
	}
}

eclipse执行结果:
    姓名:null
    年龄:0
    ----------
    姓名:张三
    年龄:28
    ----------
    好好学习,天天向上
    学习饿了要吃饭

一个常见的标准类

Student.java

package DemoCode;
/*
 * 一个标准的类通常要拥有下面四个组成部分:
 *
 * 1. 所有的成员变量都要使用private关键字修饰
 * 2. 为每一个成员变量编写一对儿Getter/Setter方法
 * 3. 编写一个无参数的构造方法
 * 4. 编写一个全参数的构造方法
 *
 * 这样标准的类也叫做Java Bean
 */
public class Student {
    private String name; // private私有成员变量
    private int age;

    public Student(){ // 无参构造

    }

    public Student(String name, int age){ // 有参构造
        this.name = name;
        this.age = age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 1000) {
            System.out.println("你给的年龄有误");
        } else {
            this.age = age;
        }
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void show(){
        System.out.println("当前name为:" + name + ", 当前age为:" + age);
    }
}

StudentDemo.java

package DemoCode;
/*
 * 学生类的测试类
 */
public class StudentDemo {
    public static void main(String[] args) {
        Student st = new Student("张三丰", 108);
        System.out.println("当前name为:" + st.getName() + ", 当前age为:" + st.getAge());
        System.out.println("===========华丽的分割线===========");
        st.setAge(109);
        st.show();
    }
}

执行结果:
    当前name为:张三丰, 当前age为:108
    ===========华丽的分割线===========
    当前name为:张三丰, 当前age为:109

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

public class Variable {
	int x; // 成员变量
	public void show() {
		int y = 0; // 局部变量

		System.out.println(x);
		System.out.println(y);
	}
}

private和public

/* 通过对象直接访问成员变量,会存在数据安全问题
 * 这个时候,我们就想能不能不让外界的对象直接访问成员变量呢?
 * 能。
 * 如何实现呢?
 * 		private关键字
 * 
 * private:
 * 		是一个修饰符
 * 		可以修饰成员变量,也可以修饰成员方法
 * 		被private修饰的成员只能在本类中访问
 * 
 * 针对private修饰的成员变量,我们会相应的提供getXxx()和setXxx()用于获取和设置成员变量的值,方法用public修饰
 */

带有private关键字的变量和方法都只能在本类中直接使用,其他类不能直接使用这个私有方法,public其他类中可直接使用。

public:

public class sum {
	public static void main(String[] args) {
		get su = new get(); // 非静态方法需要先创建对象然后才能获取
		su.add(1, 2); 
	}
}

class get{
	public void add(int a, int b) { // void是无返回值得,如有返回值(return xxx)就写对应的类型如返回int就换成int,字符串就STring...
		int num = a + b;
		System.out.println("两个数相加的值为:" + num);
	}
}

eclipse执行结果:
	两个数相加的值为:3

private:

示例代码:

public class sum {
	public static void main(String[] args) {
		get su = new get(); // 非静态方法需要先创建对象然后才能获取
		su.add(1, 2); // 这里就会出错
	}
}

class get{
	private void add(int a, int b) { // void是无返回值得,如有返回值(return xxx)就写对应的类型如返回int就换成int,字符串就STring...
		int num = a + b;
		System.out.println("两个数相加的值为:" + num);
	}
}

eclipse执行结果:
	报错:The method add(int, int) from the type get is not visible(这个类中的add方法不可见)

final关键字

一经声明在运行过程中不可重新赋值【后续有详细讲解】

final 类型 变量名称 =; // 建议全使用大写【注意:必须初始化一个值】
public class one {
	public static void main(String[] args) {
		final int A = 1;
		A = 2; // 因A不可变所以这里会报错
	}
}

this关键字

  • this:代表所在类的对象引用
    • 方法被哪个对象调用,this就代表哪个对象
  • 什么时候使用this呢?
    • 局部变量和成员变量重名

Student.java

/*
 * 学生类
 * 
 * 起名字我们要求做到见名知意。
 * 而我们现在的代码中的n和a就没有做到见名知意,所以我要改进。
 * 
 * 如果有局部变量名和成员变量名相同,在局部使用的时候,采用的是就近的原则。
 * 
 * 我们有没有办法把局部变量的name赋值给成员变量的name呢?
 * 有。
 * 
 * 什么办法呢?
 * 		用this关键字就可以解决这个问题
 * 
 * this:代表所在类的对象引用
 * 		方法被哪个对象调用,this就代表那个对象
 * 
 * 使用场景:
 * 		局部变量隐藏成员变量
 */
public class Student {
	private String name; //成员变量
	private int age;
	
	public void setName(String name) { //"张三"
		//name = name;
		this.name = name; //将形参name赋值给成员变量name(this.name代表本类中的name)
	}
	
	public String getName() {
		return name;
	}
	
	public void setAge(int age) {
		//age = age;
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
}

StudentDemo.java

/*
 * 学生类的测试类
 */
public class StudentDemo {
	public static void main(String[] args) {
		//创建对象
		Student s = new Student();
		System.out.println(s.getName()+"---"+s.getAge());
		
		s.setName("张三");
		s.setAge(28);
		System.out.println(s.getName()+"---"+s.getAge());
	}
}

构造方法

/*
 * 构造方法:
 * 		给对象的数据进行初始化
 * 
 * 格式:
 * 		方法名和类名相同
 * 		没有返回值类型,连void都不能写
 * 		没有具体的返回值
 * 
 */
class Book{
    public Book(){ //构造方法(类似Python里面的 def __init__(selef):)
        
    }
    ...
}
  • 构造方法没有返回类型,也不能定义为void
  • 构造方法名称要与本类的名称相同
  • 构造方法主要是作用是完成对象的初始化工作,它能把定义的对象参数传给对象成员

注意:构造方法分无参构造方法和有参构造方法,如果类中没有写构造方法编译器会默认创建一个无参构造方法

无参构造方法,示例代码:

public class BorrowAbook {
	public BorrowAbook() {
		
	}
	public void borrow(String name) {
		System.out.println("请前往借阅登记处领取:" + name + "。");
	}
	public static void main(String[] args) {
		BorrowAbook book = new BorrowAbook();
		book.borrow("《西游记》");
	}
}

eclipse执行结果:
	请前往借阅登记处领取:《西游记》。

有参构造方法,示例代码:

public class BorrowAbook {
	String name; //成员变量
	public BorrowAbook(String name) {
		this.name = name; //将形参name赋值给成员变量name
		
	}
	public void borrow() {
		System.out.println("请前往借阅登记处领取:" + name + "。");
	}
	public static void main(String[] args) {
		BorrowAbook book = new BorrowAbook("《西游记》");//给构造方法传参
		book.borrow(); //调用借书方法
	}
}

eclipse执行结果:
	请前往借阅登记处领取:《西游记》。

有默认值的有参构造方法:

public class EggCake {
	int eggCount;
	//创建一个有参构造方法
	public EggCake(int eggCount) {
		this.eggCount = eggCount;
		System.out.println("这个鸡蛋里面有" + eggCount + "个蛋。");
	}
	//创建一个无参构造方法(如果没有上面的有参构造方法,下面的this(1)这种写法是会报错的)
	public EggCake() {
		this(1);
        //this(1,xxx); //两个参数的情况
	}
	public static void main(String[] args) {
		EggCake cake1 = new EggCake(); //调用无参构造方法(里面默认1个)
		EggCake cake2 = new EggCake(5); //调用有参构造方法(需要传入一个数量)
	}
}

eclipse执行结果:
	这个鸡蛋里面有1个蛋。
	这个鸡蛋里面有5个蛋。

**注意:**真正意义上其实不是有默认值得构造方法,只是创建了两个同名的构造方法(Java允许构造方法或普通方法同名【这就是方法重载】,只要接收形参不同就行),一个可以接收参数一个默认赋值了一个参数而已。

使用两种方式给成员变量赋值:

Student.java

/*
 * 学生类
 */
public class Student {
	//成员变量
	private String name;
	private int age;
	
	//构造方法
	public Student() {}
	
	public Student(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	//成员方法
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
}

StudentDemo .java

/*
 * 学生类的测试类
 */
public class StudentDemo {
	public static void main(String[] args) {
		//无参+setXxx()
		Student s = new  Student();
		s.setName("张三");
		s.setAge(28);
		System.out.println(s.getName()+"---"+s.getAge());
		
		//带参构造方法进行传参
		Student s2 = new Student("林青霞",28);
		System.out.println(s2.getName()+"---"+s2.getAge());
	}
}
end不再增加
posted @ 2019-08-02 12:40  每一天,为明天。  阅读(196)  评论(0)    收藏  举报