五、面向对象简述

做~自己de王妃 提交于 2020-03-07 06:57:05

标题一、封装

1、封装的好处
    (1)安全性
    (2)隔离变化
    (3)易于使用
    (4)可重用
    (5)封装体现了程序设计的高内聚和低耦合
2、封装的实现
    (1)设置属性的可见性:private
    (2)编译问题:封装后不能使用“对象名.属性名”直接修改属性,使用get(),set()方法修改属性(public)
3、可见性和访问规则
    (1)可见性:public(不同包中可访问)、protected(同包子类可访问)、default(同包可访问)、private(同类中可访问)
    (2)JavaBean:POJO类(实体类)
    (3)构造函数:
    作用:对对象的属性进行初始化
    特点:方法名与类名保持一致;没有返回类型;没有返回值,可以只写一个return。
    注:
    (1)定制构造函数时,还需要无参构造函数,需要自己定义
    (2)使用this关键字时,必须将它放在该构造函数的第一个有效语句
4、构造函数与普通函数的区别
    (1)构造函数名需要与类名一样,普通函数名只需遵守命名规则
    (2)构造函数没有返回类型
    (3)普通函数可以多次调用,构造函数在创建对象时调用
    (4)构造函数是对象建立时,由JVM调用;普通函数是对象建立后调用
5、static
    static主要用于修饰类的属性和方法,实现静态属性和方法的共享
6、静态代码块
    Static {
    //代码
    }
    (1)在加载类的字节码后立即执行,不需要创建对象实例
    (2)在面向对象时,最后不要使用静态变量;因为常用static和final配对定义常量
    注:
        ①静态属性和静态方法随类的加载保持在方法区,实例变量随对象的建立保存在内存中。
        ②静态方法可以使用类名和对象名引用,在静态方法中只能访问静态变量和静态方法;不能访问非静态成员属性和方法,不可以使用this、super关键子。(因为静态方法优先加载)
7、单例模式(这里只列两种)
    要点:
        (1)保证某个类只能有一个实例(对象)
        (2)它必须自行创建这个实例
        (3)它必须自行向整个系统提供这个实例
    目的:保证该类只用一个对象

    步骤:
        (1)私有化构造方法
        (2)在成员位置自己创建一个对象
        (3)通过一个公共的方法访问
    常用形式:
        (1)懒汉式:

		public class SingletonClass{
			private static SingletonClass instance = null;
			private SingletonClass(){
			}
			
			//synchronized 锁,用来实现同步操作
			public static synchronized synchronized SingletionClass getInstance(){
				If(instance == null){
					Instance = new SingletonClass();
				}

				Return instance;
			}
		}

    (2)饿汉式:

		public class Singleton {
			private static final Singletion instance = new Singleton();

		private Singleton(){
			}
}

标题二、继承

1、Java中的类关系
    (1)is-a:继承关系,两个类属于同一种类
    (2)has-a:组合关系,多个类共同组成一个类
2、Java中的超类
    Object是所有Java类的父类
3、子类继承父类的语法

	修饰符 calss 子类名字 extends 父类名字{
		//类体
	}

4、继承细节
    (1)Java类只支持单继承,即只能有一个父类(接口支持多继承)
    (2)被继承的为父类(基类),继承的类为子类
    (3)子类可以通过子类名.父类静态成员名,调用父类的静态方法和静态属性。
    (4)父类私有成员方法和变量不能被子类继承(private修饰)
    (5)构造函数不能被继承
    (6)子类中可以增加新的方法和属性
5、Instanceof
    Instanceof用来判断一个对象是否是指定类所创建的实例,返回一个boolean值
6、方法的重写
    (1)重写要求:
            ①子类的重写方法和父类的被重写方法,两个方法名称和参数列表必须相同。
            ②子类中重写方法的访问权限必须大于或等于父类被重写方法的访问权限。
            ③子类重写方法的返回类型必须是父类中方法的返回类型或该类的子类。
            ④子类中重写方法不能比父类被重写方法产生更多异常。
            ⑤父类的构造函数不能被子类继承,但可以使用super关键字访问
    (2)子类对象调用重写方法后优先使用子类重写后的方法(就近原则)
    (3)子类调用父类方法,super.方法名()
7、重写和重载的主要区别
    (1)重写用于父子类中,不在同一个类;
            重载通常用于一个类中。
    (2)重写用于更改父类方法行为,或实现接口中的方法;
            重载为一个行为提供多种实现方式。
    (3)重写函数名、参数列表必须相同;子类返回类型小于等于父类返回值;子类权限修饰符(作用域)不能小于父类;子类抛出异常类型不能大于父类中方法异常类型。
            重载函数名相同,参数列表不同。与访问修饰符、返回值类型等无关。
8、super和this
    (1)用法和区别
        this:①调用本类的属性或方法(写法为this.属性名)。②调用本类构造器(写法为this())。③return this 返回对象本身
        super:①调用父类的属性和方法(写法为super*)。@调用父类构造器(写法为super())
        注:this和super调用构造方法时,都要求写在第一行。
(2)是否能够同时使用?
        ①能同时使用
            当this调用本类构造方法,super调用父类属性、方法时,能够同时使用。
        ②不能同时使用
            当super调用父类构造方法,this也调用本类构造方法,不能同时使用。
原因:this()调用的构造函数中也有super(),会与当前调用的super()冲突。
9、final(不可更改的,最终的)
    final关键字主要用于修饰类、属性和方法,以及方法的形参。
    修饰类,不可被继承。修饰方法,不可被重写。修饰变量不可被修改,就是一个常量。
10、抽象类(常用作其他类的父类)
    使用 abstract修饰的一个类
    语法:

		public abstract calss Shape {
			public abstract float area();//抽象方法
		}

注:
    (1)抽象类中不一定有抽象方法
    (2)抽象方法只能在抽象函数中定义
    (3)抽象类不能直接创建实例,只能通过子类创建
    (4)如果子类不是抽象类,子类必须实现父类中的抽象方法(通过重写实现)
11、final、static、private都不能和abstract一起使用
    (1)final
            final表示类不可以被子类继承,方法表示不可重写。
            abstract表示类不可被实例化,表示方法用于被子类重写。
    (2)static
            static 表示方法可以直接用类名调用
            abstract 表示方法没有方法体实现,不能直接调用
    (3)private
            private表示方法只能在本类中使用
            abstract表示方法用于被子类重写
12、接口
    由于Java只支持单继承,用接口来实现多继承效果
    (1)定义
            接口就是抽象方法和常量值定义的集合

			public interface interfaceName {
				//常量属性
				//抽象方法
			}

    注:
        ①方法只有声明没有定义
        ②接口中的属性默认修饰符:public static final
        ③接口中的方法默认修饰符:public abstract
        ④普通抽象类既可以包含静态常量属性,又可以变量属性;而接口不能包含变量。
        接口本质上是一个特殊的抽象类,只包含常量和方法的定义,而没有变量和方法的实现。
    (2)接口的实现
            通过implement关键字
            一个类可以实现单个或多个接口

			calss ClassName implements A,B{
				public void method1{};
				public void method2{};
			}

    (3)接口支持多继承

			public inter MutliInterface extends A,B,C{
				void method4();
			}

    (4)接口总结:
            ①接口没有构造方法,不能直接实例化
            ②接口中的所有方法是抽象方法
            ③有抽象函数的不一定是抽象类,可能是接口
            ④类通过implements实现接口,一个类可以实现多个接口
            ⑤接口中所有默认属性是静态常量,用public static final修饰
            ⑥接口中所有方法是抽象方法,用public abstract修饰
            ⑦除抽象类外,所用的类必须实现接口的所有方法
            ⑧在类中访问接口属性,不能使用super关键字(类和接口没有继承关系),直接使用“接口名.属性名”访问

标题三、多态

    1、Java多态实现的必要条件:继承、重写。
    2、多态即父类方法在子类中的不同表现(重写)。
    3、一个接口可以有多个实现类,命名:“接口名Impl“,实现implement关键字

标题四、内部类

    一个类文件中书写的另一个类(类中不能书写类)
1、成员内部类也可以访问外部类的成员方法和成员属性
    语法:
            外部类名.this.外部类方法名;
            外部类名.this.外部类属性名;
2、在内部类中,this.name中的this表示内部类
        访问外部类的字段:外部类类名.this.字段
        访问外部类的方法:外部类类名.this.方法
        访问内部类字段:this…字段
        访问内部类方法:this.方法
3、成员内部类的使用
        成员内部类必须依赖于外部类对象
        先创建外部类,再使用外部类的实例创建普通内部类(外部类实例.new()创建内部类实例)

PS:

	public class Forest{
		private int treeType=100;
		public int getTreeType(){
			return treeType;
		}
		//内部类
		class Animal{
			private String name;
			public void setName(String name){
				this.name = name;
			}
			public String getName(){
				return this.name;
			}
			public int getTreeNumber(){
				//访问外部类属性
				int type = Forest.this.treeType;
				return type;
			}
		}
	}

	//使用写法一
	//创建外部类对象
	Forest forest = new Forest();
	//创建内部类对象
	Forest.Animal animal = forest.new Animal();
	//内部类对象调用方法
	int number = animal.getTreeNumber();
	System.out.println(number);
	
	//写法二
	Forest.Animal animal = new Forest().new Animal();
	int number = animal.getTreeNumber();
	System.out.println(number);

    静态内部类可以直接new(),不需要通过外部类的实例。
4、匿名对象
    (1)没有名字
    (2)只能使用一次
        PS:new Student();
5、匿名内部类(在GUI程序中做事件处理函数)
    匿名内部类必须继承一个父类或实现一个接口
    格式:

	new 父类或接口(){
		执行代码……
	};

    匿名内部类使用后必须马上创建对象,它只能使用一次。

标题五、值交换问题

1、基本数据类型的值交换

	/*
 * 值交换
 */
public class BasicTypeConversion {

public static void main(String[] args) {
	// TODO Auto-generated method stub
	int a=10;
	int b=20;
	System.out.println("交换值之前:a="+a+"b="+b);
	changeValue(a, b);
	System.out.println("交换值之后:a="+a+"b="+b);
	
	String i="168";
	String j="198";
	System.out.println("交换值之前:i="+i+"j="+j);
	changeValue(i, j);
	System.out.println("交换值之后:i="+i+"j="+j);
	
	
}
/*
 * 执行changeValue函数后main调用栈中数据没有发生改变
 * java是值传递,执行函数时,将i和j的值拷贝给changeValue函数
 * 并没有改变i和j的值
 *PS:changeValue传值时,把常量池传进去应该就可以了,哈哈
 */
public static void changeValue(int i,int j) {
	int temp=i;
	i =j;
	j=temp;
}

public static void changeValue(String s1,String s2) {
	String temp=s1;
	s1=s2;
	s2=temp;
  }
}

2、数组类型值交换

/*
 * 交换数组两个元素位置,交换成功
 */
public class NumberArrayTypeConversion {

public static void main(String[] args) {
	// TODO Auto-generated method stub
	int[]arr= {23,10,9};
	System.out.println("交换值之前:"+Arrays.toString(arr));
	changeArr(arr, 1, 2);
	System.out.println("交换值之前:"+Arrays.toString(arr));
}
public static void changeArr(int[]arr,int index1,int index2) {
	int temp=arr[index1];
	arr[index1]=arr[index2];
	arr[index2]=temp;
}
}

3、对象值交换

/*
 * 对象值交换
* 交换成功
 */
public class ObjectConversion {

public static void main(String[] args) {
	// TODO Auto-generated method stub
	People people =new People("zs");
	changeObj(people,"ls");
	System.out.println("name="+people.name);
}
public static void changeObj(People people,String str) {
	people.name = str;
}
}

总结:以上三个案例中,
    ①基本类型值交换,只是将常量池中的数据copy了一份进行操作,并没有更改原始数据;
    ②而数组值交换和对象值交换,都直接或间接的将储存数据的数组和对象名进行了操作,更改了其中的数据。

    PS:公举个“小李子“
        一天小张感觉自己家的房子住腻了,于是他打算换个房子。然后他找到了小李,小李说行吧。晚上回家他们就偷偷把自己家的房产证偷出来复印。
        第二天,小张小李二人就来到了房地产交易中心。二人把复印件给了工作人员。只见工作人员脸色发黑,勉强挤出笑容说:“二位先生,我们需要房产证原件才能办理“。然后工作人员就走了~~编不下去了
        房产证复印件——基本数据类型传值给函数的值
        房产证——数组类型值交换或对象值交换传的值

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!