面向对象总结

面向对象的思想特点:

1.更符合现实生活思想和行为习惯;
2.角色发生了变化,从执行者变成了指挥者;
3.让复杂的事情简单化;

面向对象的三大特征:

1.封装
2.继承
3.多态

一.封装

1.封装知识点

什么是封装:
	将一个类的成员变量私有化(使用private关键字修饰),外界不能够直接访问,可以通过一些公共的方法(set/get...)间接的访问!
    
this关键字:代表当前类对象的地址值引用
    this关键字的目的:为了区分成员变量和局部变量,如:this.成员变量或this.局部变量
构造方法的特点:
	1.方法名与类名相同
    2.没有具体返回值类型
    3.连void都没有
构造方法的书写格式:
	权限修饰符 方法名(方法名与类名相同)(){//无参构造}
构造方法的作用:
	给对象的成员进行数据初始化!
构造方法怎么重载?
	无参构造方法
    有参构造方法
    注意:在写一个类的时候,如果没有提供无参构造方法,系统默认提供无参构造方法!
        如果开发者提供了有参构造方法,系统就不会提供无参构造方法,所以建议给出无参构造方法!
类的组成:成员变量,构造方法,成员方法
成员方法:
	有具体返回值类型的方法
		带形式参数
		不带形式参数
	没有具体返回值类型的方法
		带形式参数
		不带形式参数

2.封装的应用

/*
使用一个标准的类描述学生事务
属性:姓名,年龄,性别
行为:学习,玩游戏....
*/
public class Student {
	private String name;
	private int age;
	private String sex;
    //无参构造方法
	public Student() {
		super();
	}
    //有参构造方法(与无参构造方法构成重载)
	public Student(String name, int age, String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
    //get和set方法
	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 String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
    //学生的学习方法
	public void study() {
		System.out.println("study...");
	}
    //学生的玩游戏方法
    public Void playGames(){
        System.out.println("play computer games....");
    }
}
//测试类
class TestStudent{
    public static void main(String[] args){
        //方法一:通过set方法进行赋值
        Student s1 = new Student();
        s1.setName("迪丽热巴");
        s1.setAge(28);
        s1.setSex("女");
        System.out.println("姓名:"+s1.getName()+",年龄:"+s1.getAge()+",性别:"+s1.getSex());
        s1.study();
        s1.playGames();
        //方法二:通过有参构造进行初始化
        Student s2 = new Student("古力娜扎",28,"女");
        System.out.println("姓名:"+s2.getName()+",年龄:"+s2.getAge()+",性别:"+s2.getSex());
        s2.study();
        s2.playGames();
    }
}

3.如何制作文档说明书

文档说明书的制作:
		1)定义工具类 ArrayTool
		2)无参构造方法私有化,外界不能创建该类对象,里面所有的功能全都是static的	
		3)在工具类中,对所有的功能加入文档注释 
		4)针对ArrayTool.java文件产生一个文档说明
		
			打开dos--->进入到ArrayTool.java所在目录中
			javadoc -d  目录名 -author -version ArrayTool.java
/**
	这是一个针对数组操作的工具类
	@author apple
	@version V1.0
*/
//为了保证当前ArrayTool的访问权限足够大,加入public
public class ArrayTool{
	
	//私有化:外界不能创建对象访问!
	private ArrayTool(){
	
	}
	
	/**
		这个方法针对数组的遍历操作,将数组元素一一输出[元素1, 元素2, 元素3, ...]
		@param arr 需要遍历的数组
	*/
	public static void printArray(int[] arr){
		System.out.print("[");
		for(int x = 0 ; x < arr.length ; x ++){
			if(x== arr.length-1){
				System.out.println(arr[x] +"]") ;
			}else{
				System.out.print(arr[x]+", ") ;
			}
		}
		
	}
	
	/**
		该方法是获取数组中的最大值
		@param arr 在指定的数组中获取最大值
		@return 返回的就是当前数组中的最大值
	*/
	public static int getMax(int[] arr){
		//假设
		int max = arr[0] ;
		
		//遍历数组
		for(int  x =1 ; x < arr.length ; x ++){
			if(arr[x] > max){
				max = arr[x] ;
			}
		}
		
		return max ;
	}
	/**
		该方法获取数组中指定的元素出现的角标值
		@param arr 在指定的数组中查询
		@param key 表示指定的元素
		@return 如果查找到了这个元素,直接返回角标值;如果找不到,返回-1
	*/
	public static int getIndex(int[] arr,int key){
		 //假设法
		 int index = -1 ;
		 //遍历数组
		 for(int x = 0 ; x < arr.length ; x ++){
			if(arr[x] == key){
				//改变index的值
				index = x ;
				break ;
			}
		 }
		 
		 return index ;
	}
	
}
	/**
		该方法对数组进行冒泡排序
		@param arr 在指定数组中进行排序
	*/
	public static void bubbleSort(int[] arr){
        for(int x = 0;x<arr.length-1;x++){
            for(int y = 0;y<arr.length-1-i;y++){
                if(arr[y]>arr[y+1]){
                    int temp = arr[y];
                    arr[y] = arr[y+1];
                    arr[y+1] = temp;
                }
            }
        }
    }

4.代码块

Java中代码块:
		使用{}包起来的内容,就称为代码块!		
		分类:
			1)局部代码块
				在局部位置中定义的{},作用:限定变量的声明周期
			2)构造代码块
				在类的成员位置中定义{},
					特点:在当前类中,有限执行构造代码块,然后在执行构造方法...
					(每次执行构造方法之前先执行构造代码块)
					构造代码块的作用:对当前类的数据进行初始化!(很少用,笔试题!)
			3)静态代码块			
				在{}的前面加上static
				static{
					....
				}				
				静态代码块随着的类的加载而加载,由于类加载一次,静态代码块执行一次!					
	优先级:
		静态代码块 > 构造代码块 >构造方法

二.继承

1.继承知识点

继承:将一些类共性的内容抽取出来,单独定义在一个类中,让这个独立的类和多个类产生一种关系,这种关系叫作继承关系(extends)
继承的好处:
	1.提高了代码的复用性
	2.提高了代码的维护性
	3.类与类的产生的继承关系是多态的前提
继承的格式:
	class 父类名{}
	class 子类名 extends 父类名{}
继承的特点:
	1.Java中类与类只能单继承,不支持多继承
	2.Java中类与类可以多层继承
	如:class A{}-----class B extend A{}----class C extends B{}
继承的注意事项:
	1.子类继承父类,不能继承父类的私有的成员变量和私有的成员方法;
	原因:被private修饰的成员外界访问不到,但是可以通过公共的方法来间接访问
	2.子类继承父类,不能继承父类的构造方法,但是可以通过super关键字间接来访问
存在继承关系,类成员的访问问题:
	1.子类和父类中的成员变量不一样的情况	:分别访问即可!
	2.子类和父类中的成员变量一样: 遵循就近原则!
		1).先在局部位置找,如果存在就使用
		2).如果局部位置没有,那么就在子类中的成员位置找,如果有,则使用!
		3).如果子类的成员位置没有,那么久在父类的成员位置找,如果有就使用!
		4)如果父类的成员位置都没有,那么就访问报错,报错原因为不存在这个变量!
子类继承父类,关于构造方法的问题:
	子类的所有构造方法默认访问父类的无参构造方法!
	为什么要访问父类的无参构造方法?
	构造方方法的目的:就是为了数据初始化
	由于存在继承关系,创建的是子类对象,对子类初始化的时候执行构造方法,可能会用到父类的数据,所以必须先让父类初始化(会执行父类的构造方法),父类初始化完毕了才是子类初始化(分层初始化)!
	*注意*:每一个子类的构造方法的第一句话是super() ;可以不写,super:代表的是父类的空间标识(大代表父类对象的引用地址)
	注意事项:子类默认访问父类的无参构造,如果父类没有提供无参构造,会出现什么情况,怎么解决!
	会出现编译报错,因为父类存在有参的无参构造方法,系统不会提供无参构造,又由于所有子类的构造方法都默认访问父类的无参,所以报错!
	解决办法:
		1.手动给出父类的无参构造方法
		2.可以让子类所有的构造方法,默认访问父类的有参构造方法
			在子类的的构造方法的第一句话加上super(xxxx);子类中所有的构造方法的一个只要能让父类初始化即可!
		3.通过子类的有参构造方法,访问this()本类的无参构造方法,再通过本类的无参构造方法,访问父类的有参构造方法(让父类先进行初始化)
this和super的区别
	this代表的当前对象的地址值引用
	super代表父类对象的地址值引用
	访问区别:
		this.成员变量:访问的是当前类的的成员变量
		super.成员变量:访问的是父类的成员变量
		
		this.成员方法名():访问的是当前类的成员方法
		super.成员方法名():访问的是父类的成员方法
		
		this():访问的是本类的无参构造方法
		super():访问的是父类的无参构造方法
		
		this(xx):访问的本类的有参构造方法
		super(xxx):访问的是父类的有参构造方法
继承关系中子类变量名和父类变量名一致的情况:先在子类的局部位置中找,然后在子类的成员位置中找,最后在父类的中的成员位置中找(成员方法名称与成员变量一致)
方法重载和方法重写的区别:
	方法重载:方法名相同,参数列表不同(参数的个数和顺序),与返回值无关
	方法重写:子类继承父类的时候,子类出现和父类一模一样的方法
final关键字的特点:
	final:状态修饰符,最终的,无法更改的!
	final修饰类,该类不能继承
	final修饰变量,该变量此时一个常量!
	final修饰成员方法,该方法不能被重写!
final修饰基本数据类型的变量和引用数据类型的区别:
	final修饰基本数据类型则它的数值不能再改变了(具体的数值)
	final 修饰的引用数据类型,它的地址值不能再改变了(成员变量的值不影响)

2.继承的应用

/*
猫狗案例
 * 
 * 猫 事物 
 * 		属性:姓名,年龄,颜色...
 * 		行为:猫吃鱼
 * 			抓老鼠..   
 * 			吃 跑 
 * 狗 事物
 * 		属性:姓名,年龄,颜色...
 * 		行为:狗看门
 * 			吃 跑
 *将猫和狗的共性内容,提前到独立类中----->动物类 Animal
 *狗和猫继承自动物类
*/
public class Animal {
	private String name;
	private int age;
	private String color;
	//无参构造
	public Animal() {
		super();
	}
	//创建有参构造
	public Animal(String name, int age, String color) {
		super();
		this.name = name;
		this.age = age;
		this.color = color;
	}
	//get和set方法
	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 String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	//定义动物的方法
	public void eat() {
		System.out.println("eat...");
	}
	public void run() {
		System.out.println("running...");
	}
}
//狗类继承动物类
public class Dog extends Animal {
	//无参构造
	public Dog() {
		super();
	}
	//有参构造
	public Dog(String name, int age, String color) {
		super(name, age, color);
	}
	public void seeDoor() {
		System.out.println("see door.......");
	}
    public void eat(){
        System.out.println("吃骨头....");
    }
}
//猫类继承动物类
public class Cat extends Animal {
	//无参构造
	public Cat() {
		super();
	}
	//有参构造
	public Cat(String name, int age, String color) {
		super(name, age, color);
	}
	public void catchMouse() {
		System.out.println("我可以抓老鼠....");
	}
	public void eat() {
		System.out.println("猫吃鱼....");
	}
}
//测试类
class Test{
    public static void main(String[] args){
        //测试猫
        Cat c = new Cat();
        c.catchMouse();
        c.run();
        c.eat();
        //测试狗
        Dog d = new Dog();
        d.eat();
        d.run();
        d.seeDoor();
    }
}

三.多态

1.多态的知识点

多态:一个事物在不同时刻显示的不同状态(在堆内存中的变化)
多态的前提条件:
	1).必须存在继承关系
	2).要有要方法的重写(指的是非静态的方法)
	3).要存在父类的引用指向子类的对象(向上转型)
		格式:父类名 对象名 = new 子类名();
多态的成员访问特点:
	1.成员变量:编译看左,执行看左
	2.成员方法(非静态的):编译看左,运行看右(因为存在子类覆盖了父类的方法:方法的重写)
	3.静态的成员方法:编译看左,执行看左
		如果子类出现了与父类一模一样的静态方法,静态方法和类相关,不存在重写,访问方式是类名.方法名();
	4.构造方法:由于存在继承关系,还需要分层初始化!
多态的好处:
	1.提高的代码的扩展性
	2.提高了代码的复用性,维护性
多态的弊端:
	不能够访问子类的特有功能!
	解决方式:
		1.创建子类具体类对象:    子类名 对象名 = new 子类名();
			对象自名.访问子类自己的功能;(比较消耗内存空间)
		2.多态的第三条件:父类的引用指向子类的对象(向上转型)
			父类名 对象名  = new 子类名();
			再通过父类的引用强制转化为子类的引用(向下转型)
			子类名 对象名 = (子类名)父类对象名;(不需要重新new对象,在堆内存中是比较节省内存空间的)
			注意:使用向下转型必须先使用向上转型,否则会出现ClassCastException错误!

2.多态的应用

/*
 * 	猫狗案例,多态版进行测试
 * 
 *   猫和狗:
 *   		属性:姓名,年龄,颜色
 *   		行为:吃/和睡的功能
 *   共性内容---->动物类:Animal
 *   		属性:姓名,年龄,颜色
 *   		行为:吃/和睡的功能
 *   		提供:对外的公共访问方法以及无参/有参构造方法
 *   猫类继承自动物类
 *   		提供无参/有参
 *   		覆盖吃和睡的功能
 *   		特有功能:
 *   			猫抓老鼠
 *   狗类继承自动物类
 *   		提供无参/有参
 *   		覆盖吃和睡的功能
 *  	 特有功能
 *  		狗抓兔子
 */
public class Animal {
	private String name ;
	private int age ;
	private String color ;
	
	public Animal() {
		super();
	}
	
	public Animal(String name, int age, String color) {
		super();
		this.name = name;
		this.age = age;
		this.color = color;
	}

	//alt+shift+s--r
	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 String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
	
	public void eat() {
		System.out.println("吃饭...");
	}
	public void sleep() {
		System.out.println("睡觉...");
	}	
}
//猫类
public class Cat extends Animal {
	public Cat() {
		super();
	}
	public Cat(String name, int age, String color) {
		super(name, age, color);
	}
	public void eat() {
		System.out.println("猫吃鱼...");
	}
	public void sleep() {
		System.out.println("猫趴着睡觉...");
	}
	//特有功能
	public void catchMouse() {
		System.out.println("猫抓老鼠...");
	}
}
//狗类
public class Dog extends Animal {
	public Dog() {
		super();
	}
	public Dog(String name, int age, String color) {
		super(name, age, color);
	}
	
	public void eat() {
		System.out.println("狗吃狗粮...");
	}
	public void sleep() {
		System.out.println("猫侧着睡觉...");
	}	
	//特有功能
	public void catchRabit() {
		System.out.println("狗抓兔子...");
	}
}
//测试类
public class Test {
	public static void main(String[] args) {
		//多态方式测试
		//测试猫
		//方式1:无参构造+setXXX(XX xx)
		Animal a = new Cat() ; //向上转型
		a.setName("tom");
		a.setAge(4);
		a.setColor("白色");
		System.out.println(a.getName()+"---"+a.getAge()+"---"+a.getColor());
		a.eat();
		a.sleep();
		//特有功能
	 //	a.catchMouse() ;
		
		//向下转型:
		Cat c = (Cat)a;
		c.catchMouse();
		System.out.println("------------------------------------------");
		
		//方式2:有参构造方法赋值
		Animal a2 = new  Cat("加菲猫", 3, "黄色") ;
		System.out.println(a2.getName()+"---"+a2.getAge()+"---"+a2.getColor());
		a2.eat();
		a2.sleep() ;
		
		//向下转型
		Cat c2 = (Cat)a2;
		c2.catchMouse();
	}
}