JAVASE-OOP面向对象

OOP面向对象
–1,面向对象是一种思想.相对面向过程而言的,相对简单.
–2,万物皆对象
–3,面向对象的特征:
–封装性,把相关的数据封装成一个“类”组件
–继承性,是子类自动共享父类属性和方法,这是类之间的一种关系
–多态,增强软件的灵活性和重用性
–4,类和对象的创建和使用

	package cn.tedu.oop;
	//测试 类和对象
	//一个.java文件中,可以包含多个类.只不过,只能有一个类,被public修饰.
	//而且,被public修饰的类名就是.java文件名.
	public class Test6_Class {
		public static void main(String[] args) {
			//根据汽车类这个模板,创建一个汽车对象来干活
			//使用new关键字,创建对象
	//		new Car();//匿名对象
			Car BMW = new Car();//对象的名字叫BMW
			
			//TODO 已经根据模板产生对象了,能不能使用模板里的功能????
			
		}
	}
	//使用class关键字创建汽车类 ,用来描述汽车事物
	class Car{
		//描述事物的特征 -- 成员属性/实例变量/成员变量(在类里方法外)
		//型号,颜色,价格,配置
		double price ;
		String color ;
		String model ;
		char peizhi ;
		//描述事物的功能 -- 成员方法/成员函数
		//前进  后退
		public void run() {
			System.out.println("run()...");
		}
		public void back() {
			System.out.println("back()...");
		}
	}

类和对象的创建和使用
–1,代码

	package cn.tedu.oop;
	//测试 类和对象
	//一个.java文件中,可以包含多个类.只不过,只能有一个类,被public修饰.
	//而且,被public修饰的类名就是.java文件名.
	public class Test6_Class {
		public static void main(String[] args) {
			//根据汽车类这个模板,创建一个汽车对象来干活
			//使用new关键字,创建对象
	//		new Car();//匿名对象
			Car c = new Car();//对象的名字叫BMW
			//使用模板里的方法
			c.run();
			c.back();
			//设置c对象的信息
			c.price = 10.9 ;
			c.peizhi = '高' ;
			c.color = "black";
			c.model = "X6";
			//使用模板里的属性/变量
			System.out.println( c.price );//0.0
			System.out.println( c.peizhi );//\u0000
			System.out.println( c.color );//null
			System.out.println( c.model );//null
		}
	}
	//使用class关键字创建汽车类 ,用来描述汽车事物
	class Car{
		//描述事物的特征 -- 成员属性/实例变量/成员变量(在类里方法外)
		//型号,颜色,价格,配置
		double price ;//小数类型的默认值是0.0
		String color ;//引用类型的默认值是null
		String model ;
		char peizhi ;//char类型的默认值是\u0000
		
		//描述事物的功能 -- 成员方法/成员函数
		//前进  后退
		public void run() {
			System.out.println("run()...");
		}
		public void back() {
			System.out.println("back()...");
		}
	}

–2,分析手机事物:
– 属性:颜色,尺寸,品牌,价格。。。
– 行为:打电话,发短信,听音乐。。。。
– 测试:

		package cn.tedu.oop;
		//练习手机类
		public class Test1_Class {
			public static void main(String[] args) {
				//TODO 创建手机对象测试
				//new Phone().call();//匿名对象--只干一件事情
				Phone p = new Phone() ;
				//调用模板里的方法
				p.call();
				p.music();
				p.message();
				//设置p对象的具体信息
				p.color = "red" ;
				p.size = 5.7 ;
				p.pinpai = "HUAWEI" ;
				p.price = 5999.9 ;
				//调用模板里的属性
				System.out.println(  p.color  );//null
				System.out.println(  p.size  );//0.0
				System.out.println(  p.pinpai  );//null
				System.out.println(  p.price  );//0.0
			}
		}
		//创建手机类 描述手机事物
		class Phone{
			//属性--成员变量--颜色,尺寸,品牌,价格
			String color ;
			double size ;
			String pinpai ;
			double price ;
			//行为--成员方法--打电话,发短信,听音乐
			public void call() {
				System.out.println("call()..");
			}
			public void message() {
				System.out.println("message()..");
			}
			public void music() {
				System.out.println("music()..");
			}
		}

–3,创建多个对象测试

	--代码
		package cn.tedu.oop;
		//练习手机类
		public class Test1_Class {
			public static void main(String[] args) {
				//创建手机对象测试
				new Phone().call();//匿名对象--只干一件事情
				new Phone().music();//匿名对象--只干一件事情
				
				Phone p = new Phone() ;
				//调用模板里的方法
				p.call();
				p.music();
				p.message();
				//设置p对象的具体信息
				p.color = "red" ;
				p.size = 5.7 ;
				p.pinpai = "HUAWEI" ;
				p.price = 5999.9 ;
				//调用模板里的属性
				System.out.println(  p.color  );
				System.out.println(  p.size  );
				System.out.println(  p.pinpai  );
				System.out.println(  p.price  );
				//TODO 创建p2 p3对象测试
				Phone p2 = new Phone() ;
				//调用模板里的方法
				p2.call();
				p2.music();
				p2.message();
				//设置p对象的具体信息
				p2.color = "white" ;
				p2.size = 6.3 ;
				p2.pinpai = "VIVO" ;
				p2.price = 3999.9 ;
				//调用模板里的属性
				System.out.println(  p2.color  );
				System.out.println(  p2.size  );
				System.out.println(  p2.pinpai  );
				System.out.println(  p2.price  );

				Phone p3 = p2 ;
				System.out.println(  p3.color  );
				System.out.println(  p3.size  );
				System.out.println(  p3.pinpai  );
				System.out.println(  p3.price  );
			}
		}
		//创建手机类 描述手机事物
		class Phone{
			//属性--成员变量--颜色,尺寸,品牌,价格
			String color ;
			double size ;
			String pinpai ;
			double price ;
			//行为--成员方法--打电话,发短信,听音乐
			public void call() {
				System.out.println("call()..");
			}
			public void message() {
				System.out.println("message()..");
			}
			public void music() {
				System.out.println("music()..");
			}
		}

封装
–1,通过private关键字实现封装,来提高程序的安全性.可以封装成员变量,也可以封装成员方法.被private修饰后,只能在本类中可见.
–2,练习1:封装学生类

	package cn.tedu.oop;
	//测试封装
	public class Test2_Private {
		public static void main(String[] args) {
			// 创建Student对象测试
			Student s = new Student();
			s.coding();
			//s.chiji();//2,因为chiji()已经被封装了,外界无法使用!!
			//设置属性的值
	//		s.name="jack";//4,因为name已经被封装了,外界无法使用!!
	//		s.age=20 ;
			s.setName("jack");
			s.setAge(20);
			//获取属性的值
	//		System.out.println( s.name );//4,因为name已经被封装了,外界无法使用!!
	//		System.out.println( s.age );//0
			System.out.println( s.getName() );//jack
			System.out.println( s.getAge() );
	//		System.out.println( s.score );//0.0
		}
	}
	// 提供Student类
	class Student{
		//特征
		private String name ;
		//5,当属性被private后,外界就没法直接获取或者设置了!!--提供公共的访问方式
		//提供公共的设置方式 setXxx()
		public void setName(String n){
			//拿到你提供的n的值,给name属性赋值
			name = n ;
		}
		//提供公共的获取方式 getXxx()
		public String getName(){
			return name;//把name属性的值,返回给外界的调用位置
		}
		//TODO  封装
		private int age ;
		public void setAge(int a) {
			age = a;
		}
		public int getAge(){
			return age ;
		}
	//自动-右键-source-generate getters and setters-select all-ok
		private double score ;
		public double getScore() {
			return score;
		}
		public void setScore(double score) {
			this.score = score;
		}
		//TODO 封装
		private String addr ;
		private long id ;
		public String getAddr() {
			return addr;
		}
		public void setAddr(String addr) {
			this.addr = addr;
		}
		public long getId() {
			return id;
		}
		public void setId(long id) {
			this.id = id;
		}
		//行为
		public void coding() {
			//3,  在类里, 提供间接的访问方式
			chiji();
			System.out.println("coding()...");
		}
		//1,通过private关键字,实现封装.只能在本类中访问
		private void chiji() {
			System.out.println("chiji()...");
		}
	}

构造方法
–1,用来创建对象 或者 完成对象的初始化.
–2,构造方法可以重载(方法名相同,参数列表不同)
–语法: 修饰符 类名([参数列表]){ 方法体 }
–3,构造方法创建对象

	package cn.tedu.oop;
	//测试 构造方法
	//总结
	//1, 构造方法的语法: 修饰符 类名(参数列表){}
	//2, 构造方法的触发时间节点: 创建对象/new/实例化
	//3, 构造方法可以重载,目的是为了,方便外界比较灵活的创建对象
	public class Test3_Constructor {
		public static void main(String[] args) {
			//1,创建Teacher对象 
			Teacher t = new Teacher();//触发无参构造方法
			//4,创建Teacher对象 -- 触发含参构造方法
			Teacher t2 = new Teacher("张慎政");//触发String类型的含参构造
			Teacher t3 = new Teacher(39);//触发int类型的含参构造
			Teacher t4 = new Teacher("张慎政",39);//触发String和int的含参构造
		}
	}
	//提供Teacher类
	//构造方法语法:  修饰符 类名([参数列表]){ 方法体 }
	class Teacher{
		//2, 无参构造方法  默认就存在 ---前提是:不要只提供含参构造,否则就真没了!!
		public Teacher() {
			System.out.println(123);
		}
		//3, 含参构造方法 的重载 -- 方法名相同但是参数列表不同!!
		public Teacher(String name) {
			System.out.println("老师叫:"+name);
		}
		//重载的构造方法
		public Teacher(int age) {
			System.out.println("老师"+age+"岁.");
		}
		//TODO 重载的构造方法
		public Teacher(String name,int age){
			System.out.println("老师叫:"+name+",今年:"+age+"岁.");
		}
	}

–4, 构造方法赋值

	package cn.tedu.oop;
	//测试 构造方法
	//总结
	//1, 构造方法的语法: 修饰符 类名(参数列表){}
	//2, 构造方法的触发时间节点: 创建对象/new/实例化
	//3, 构造方法可以重载,目的是为了,方便外界比较灵活的创建对象
	public class Test3_Constructor {
		public static void main(String[] args) {
			//1,创建Teacher对象 
			Teacher t = new Teacher();//触发无参构造方法
			//4,创建Teacher对象 -- 触发含参构造方法
			Teacher t2 = new Teacher("张慎政");//触发String类型的含参构造
			Teacher t3 = new Teacher(39);//触发int类型的含参构造
			Teacher t4 = new Teacher("张慎政",39);//触发String和int的含参构造
		}
	}
	//提供Teacher类
	//构造方法语法:  修饰符 类名([参数列表]){ 方法体 }
	class Teacher{
		String name ;
		//2, 无参构造方法  默认就存在 ---前提是:不要只提供含参构造,否则就真没了!!
		public Teacher() {
			System.out.println(123);
		}
		//3, 含参构造方法 的重载 -- 方法名相同但是参数列表不同!!
		public Teacher(String n) {
			name = n ; // ----------!!!构造方法还可以给成员变量赋值!!!---------
			System.out.println("老师叫:"+n);
		}
		//重载的构造方法
		public Teacher(int age) {
			System.out.println("老师"+age+"岁.");
		}
		//重载的构造方法
		public Teacher(String name,int age){
			System.out.println("老师叫:"+name+",今年:"+age+"岁.");
		}
	}

在这里插入图片描述
构造代码块和局部代码块
–1,代码块就是一段代码被一对花括号包起来的现象.如: {…}
–2,代码块随着位置的不同,作用和意义都不同.
–3,代码块如果在成员位置(在类里方法外),叫做构造代码块.
–4,代码块如果在局部位置(方法里),叫做局部代码块.
–5,构造代码块------用来提取构造方法的共性
–6,局部代码块------用来控制变量的作用范围
–7,测试

	package cn.tedu.oop;
	//测试 代码块
	//总结
	//1,构造代码块 -- 位置:类里方法外 -- 作用:抽取构造方法的共性
	//2,局部代码块 -- 位置:方法里 -- 作用:控制变量的作用范围
	//3,执行顺序: 构造代码块  > 局部代码块
	//4,触发时机: 
	//当创建对象时,会触发构造方法,但是,如果有构造代码块,构造代码块>构造方法
	//当方法被调用时,才触发局部代码块
	public class Test1_Block {
		public static void main(String[] args) {
			//创建Person对象测试
			new Person() ;
			new Person("jack").show() ;
		}
	}
	//创建Person类
	class Person{
		String country ;
		//1, 构造代码块---位置是在类里方法外  -- 用来抽取构造方法的共性
		//2, 在创建对象时,先触发构造代码块再触发构造方法
		{
			country = "中国人";//抽取构造方法的共性
			System.out.println("构造代码块");
		}
		//构造方法
		public Person() {
			System.out.println("无参构造"+country);
		}
		public Person(String name) {
			System.out.println("含参构造"+country);
		}
		
		public void show() {
			//4,局部代码块--位置是在方法里--作用是控制变量的作用范围
			{	
				int sum = 10 ;
				System.out.println(sum);
				System.out.println("局部代码块");
			}
			//System.out.println(sum);//已经超出了sum的作用范围
		}
		
	}

this关键字
–1,代表本类对象的引用对象
–2,当变量名相同时

	package cn.tedu.oop;
	//测试 this关键字
	//总结
	//当局部变量名和成员变量名相同时,会优先使用局部变量,
	//想要使用成员变量必须通过this调用
	public class Test2_This {
		public static void main(String[] args) {
			//TODO 创建Student对象测试
			new Student().show(); 
		}
	}
	//创建Student类
	class Student{
		int count ; //成员变量:位置在类里方法外,不用赋值也有默认值
		int sum = 20 ; 
	//1,当成员变量 和 局部变量 同名时,通过this关键字调用成员变量!
		
		//提供普通方法
		public void show() {
			int sum = 10 ;//局部变量:位置在方法里,必须赋值
			System.out.println(sum);//就近原则,使用了局部变量10
			//TODO 如何使用成员变量sum呢?--创建一个本类的对象
	//2,this代表的是本来对象的引用,底层会自动创建本类对象Student this = new Student();
			System.out.println( this.sum );//使用了成员变量20
			
			System.out.println( count );//0
		}
	}

–3构造方法间的调用

	package cn.tedu.oop;
	//测试  this -- 可以在构造方法间 实现互相调用
	public class Test3_This2 {
		public static void main(String[] args) {
			//创建对象测试
			new ThisDemo() ;
	//		new ThisDemo(10) ;
		}
	}
	//创建ThisDemo
	class ThisDemo{
		//提供构造方法
		public ThisDemo() {
			//2,在无参构造中  调用  含参构造
			this(5);//3,this关键字出现在构造方法中时,必须是第一条语句!!
			System.out.println("无参构造方法");
		}
		public ThisDemo(int a) {
			//1,在含参构造中  调用  无参构造
			//this() ;
			System.out.println("含参构造方法"+a);
		}
	}

继承
–1,继承的初衷:提高代码的复用性.
–2,好处:
假设没有继承结构,每种小动物都需要提供吃的功能,可能得写100万次,这个业 务相同代码量非常大降低了开发效率.产生继承后,只需要把共性的吃的功能在父 类里写一次即可,哪个小动物需要提供吃,就来继承父类.
–3,特点
–使用extends关键字
–相当于子类把父类的功能复制了一份
–java只支持单继承
–继承可以传递(爷爷,儿子,孙子的关系)
–不能继承父类的私有成员
–继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展
–像是is a 的关系
–4,入门案例

	package cn.tedu.oop;
	//测试 继承	
	public class Test4_Extends {
		public static void main(String[] args) {
			//TODO 创建Dog对象测试
			Dog d = new Dog();
			d.eat();//使用了父类的eat()
	//		System.out.println( d.sifangmoney );//5,父类中的private资源不能继承
			System.out.println( d.country ); //7,继承具有传递性,使用了爷爷类的功能
		}
	}
	class Yeye{
		String country = "中国人";
	}
	//1,创建父类,抽取共性功能,来提高代码的复用性
	class Animal extends Yeye{
		//4,在父类中,如果不想让子类继承,可以用private修饰
		private double sifangmoney = 100000;
		public void eat() {
			System.out.println("吃啥都行");
		}
	}
	//2,使用extends关键字,表示继承关系--java只支持单继承
	class Dog extends Animal{
		//3,子类把父类的功能复制了一份
	}
	class Cat extends Animal{//6,像是is a的关系--强制的依赖关系
	}
	//.......

–5,super关键字
–代表的是父类对象的一个引用
–用来在子类中使用父类的功能
–如果用在构造方法中,super必须是第一条语句.
–6,方法的重写Override
– 发生在父类子间的现象
– 子类继承父类后,就可以使用父类的所有功能.
– 当子类想要修改父类原有的功能时,就会发生方法的重写/复写/覆盖
– 重写的要求 : 继承关系 + 在子类中方法的声明/签名 必须和 父类一模一样
– 方法的声明/签名 包括: 方法返回值 方法名(参数列表)

继承中的用法
–1,构造方法
package cn.tedu.oop;
//测试 继承中 的构造方法
//总结
//1, 子类的构造方法中,默认就会存在super() – 去找父类的无参构造
//2, 如果父类没有提供无参构造,只提供了含参构造–只能在子类构造方法中调用父类的含参构造
//3, 提示:每个类,最好都提供一个无参构造.

	public class Test7_UseExtends3 {
		public static void main(String[] args) {
			//2,当你创建了子类对象时,实际上,会先触发父类的构造方法,然后是子类的构造方法
			Erzi2 zi = new Erzi2();
		}
	}
	class Baba2{
		//4,无参构造 ,暂时不用也要提供,为了自己创建对象方便,或者为了子类.
		public Baba2() {}
		public Baba2(int a) {
			System.out.println("父类的构造方法");
		}
	}
	class Erzi2 extends Baba2{
		public Erzi2() {
	//1,子类的构造方法中,默认就会存在super()--会去找父类的无参构造
			//super();
			//3,如果父类中,没有无参构造呢? --只能调用父类的含参构造!!
			//4,super关键字,如果在构造方法中出现,位置上必须是第一条语句!!类似于this
			super(10) ;
			System.out.println("子类的构造方法");
		}
	}

–2,成员变量

	package cn.tedu.oop;
	//测试 继承中  的成员变量
	//总结
	//1,在发生了继承关系后,子类中 想要用 父类的资源 ,最好都加上super
	public class Test5_UseExtends {
		public static void main(String[] args) {
			Zi zi = new Zi();
			System.out.println( zi.skin );//1,使用了父类的skin
			zi.show(); //3,使用子类的show()
		}
	}
	class Fu{
		String skin = "yellow" ;
		int num = 30 ;//4,当父类的变量 和  子类的变量 同名时
	}
	class Zi extends Fu{
		int num = 20 ;//成员变量
		//2,子类自己扩展的功能
		public void show() {
			int num = 10 ;//局部变量
			System.out.println(num);//10,局部变量
			System.out.println(this.num);//成员变量
			System.out.println(super.skin);//使用父类的skin--不同名时直接用!!
			//5,在子类中,如何使用父类的num --- 通过super关键字
	//super代表父类对象的引用,相当于底层帮你创建了父类对象-- Fu super = new Fu();
			//使用父类的num--同名了,用super调用父类资源
			System.out.println( super.num );
		}
	}

–3,成员方法

	package cn.tedu.oop;
	//测试 继承中  的成员方法
	//总结
	//1,子类继承了父类后
	//--可以使用父类的所有功能(除了private的)
	//--还可以进行自己特有的功能扩展
	//--继承后,如果某些功能的业务发生了改变,还可以重写
	//--重写的要求是: 子类的 方法声明 必须 和父类 一模一样
	public class Test6_UseExtends2 {
		public static void main(String[] args) {
			//创建子类对象测试
			Erzi zi = new Erzi();
			//4,在重写前,使用的是父类的吃的功能.重写后,使用了子类的功能
			zi.eat();
			zi.coding();//子类可以使用自己特有的扩展功能
		}
	}
	class Baba{
		public void eat() {
			System.out.println("爸爸在吃肉");
		}
	}
	class Erzi extends Baba{
		//1,子类可以使用父类的方法--发生了继承关系
		//2,子类可以进行功能拓展
		public void coding() {
			System.out.println("学java!");
		}
		//3,子类想要修改父类的原有功能 -- 方法重写/覆盖/复写
		//要求:子类的方法声明 必须和 父类一模一样
		public void eat() {
			//5,虽然发生了方法重写,但是,对于父类原有功能没有任何影响!!!
			//super.eat();//调用父类的功能,查看一下
			System.out.println("娃在喝汤");
		}
	}

程序设计
– 假设现在有一个汽车类,我们可以根据汽车类创建很多汽车对象。
– 需求:
1,创建汽车类。提供启动、停止、运行功能
2,创建子类,继承汽车类。覆盖/重写 启动和停止功能
3,创建子类对象,进行子类的功能测试
– 代码 :

	package cn.tedu.oop;
	public class Test8 {
		public static void main(String[] args) {
			Audi audi = new Audi();
			audi.start();//使用了父类的
			audi.stop();//使用了父类的
			audi.run();//使用了父类的
			
			BMW bmw = new BMW();
			bmw.start();//重写了,使用了子类的
			bmw.stop();//重写了,使用了子类的
			bmw.run();//没重写,使用了父类的
		}
	}
	//创建父类
	class Car{
		//提供启动、停止、运行功能
		public void start() {
			System.out.println("已启动!");
		}
		public void stop() {
			System.out.println("已停止!");
		}
		public void run() {
			System.out.println("冲鸭!");
		}
	}
	//创建子类
	class BMW extends Car{
		//BMW继承后,想改启动和停止
		public void start() {
			System.out.println("BMW已启动!");
		}
		public void stop() {
			System.out.println("BMW已停止!");
		}
	}
	//Audi直接继承,没有修改功能的需求
	class Audi extends Car{
	}

static关键字
–1,特点
1、 可以修饰成员变量,成员方法
2、 随着类的加载而加载,优先于对象加载
3、 只加载一次,就会一直存在,不再开辟新空间
4、 全局唯一,全局共享
5、 可以直接被类名调用
6、 静态只能调用静态,非静态可以随意调用
7、 static不能和this或者super共用,因为有static时可能还没有对象
–2,入门案例

	package cn.tedu.staticdemo;
	//测试   static
	public class Test1_Static {
		public static void main(String[] args) {
			//3,如何调用静态资源呢? -- 静态资源多了一种调用方式,可以类名直接调用
			//4,随着类的加载而加载,优先于对象加载
			Person.test();
			System.out.println( Person.age );
			
			//TODO 创建对象测试
			Person p = new Person();
			p.show();
			System.out.println( p.name );
			//2,如何调用静态资源呢? -- 通过对象访问
			p.test();
			System.out.println( p.age );
			
			//5,静态资源是共享资源,在多个对象间数据共享
			Person p2 = new Person();
			Person p3 = new Person();
			p2.age = 10 ;
			System.out.println( p3.age );//10,age在p2和p3间共享
		}
	}
	class Person{
		//静态资源
		//1,static 可以用来修饰成员变量和成员方法
		static int age;
		static public void test() {
			//this.show();--Cannot use this in a static context
			//super. --Cannot use this in a static context
			//7, 静态资源 可以调用 普通资源吗? -- 不可以-静态只能调用静态
	//		show();
	//		System.out.println(name);
			
			System.out.println("test()...");
		}
		//普通资源
		String name ;
		public void show() {
			//6,普通资源 可以调用 静态资源吗? -- 可以
			test();
			System.out.println(age);
			
			System.out.println("show()...");
		}
	}	

静态代码块、构造代码块、局部代码块
–1,静态代码块通常用于完成项目的初始化.
–2,静态资源会随着类的加载而加载,第一时间加载进内存,并一直贮存在内存中,直到类消失静态资源才消失.
–3,静态资源只会被加载一次
–4,静态代码块,存在的位置是成员位置.如:static{…}
–5,测试

	package cn.tedu.staticdemo;
	//测试 代码块
	//总结
	//静态代码块 --位置:在成员位置--作用:完成项目初始化--触发节点:类加载时
	//构造代码块 --位置:在成员位置--作用:抽取构造方法的共性--触发节点:创建对象时
	//局部代码块 --位置:在局部位置--作用:控制变量的作用范围--触发节点:方法执行时
	//执行顺序:静态代码块  > 构造代码块 > 局部代码块
	public class Test2_Block {
		public static void main(String[] args) {
			new BlockDemo();//触发了构造代码块和构造方法
			new BlockDemo();
			new BlockDemo().test();//触发了构造代码块和构造方法和局部代码块
		}
	}
	class BlockDemo{
		//静态代码块
		static{
			System.out.println("静态代码块");
		}
		//构造代码块
		{
			System.out.println("构造代码块");
		}
		//构造方法
		public BlockDemo() {
			System.out.println("构造方法");
		}
		//局部代码块
		public void test() {
			{
				System.out.println("局部代码块");
			}
		}
	}

final关键字
–1,在继承结构中,父类的功能可以全都给子类用. 但是当子类想要修改功能 时,会发生方法的重写现象.子类想改哪个方法都可以重写.如果想要限制, 不让子类随便重写.可以把父类的功能用final修饰成最终的.
–2,测试

	package cn.tedu.oop;
	//测试 final关键字
	public class Test3_Final {
		public static void main(String[] args) {
			Zi zi = new Zi();
			zi.eat();//重写前使用了父类的功能,重写后使用子类的功能
			
			//zi.age = 20;//修改了age的值
			System.out.println(zi.age);//使用了age的值
		}
	}
	//1,final修饰类不能被继承--The type Zi cannot subclass the final class Fu
	//final class Fu{
	class Fu{
		//2,final修饰方法可以被继承,但是不能被重写--Cannot override the final method from Fu
		final public void eat() {
			System.out.println("Fu...eat()...");
		}
	//3,final修饰的是常量,值不能被修改--The final field Fu.age cannot be assigned
		final int age = 1_000 ;
	}
	class Zi extends Fu{
		/*
		 * //需要修改父类原有的功能--方法重写--方法声明必须和父类一模一样
		 * 
		 * @Override public void eat() { System.out.println("Zi...eat()"); }
		 */
	}

多态
–1,多态是指同一个对象有多种形态.
–2,多态是为了统一调用标准—父类就是标准,一切向父类看齐
–3,好处是:不关心具体的类型,屏蔽了子类之间的不同,把子类都会当做父类来看,做出统一的编程,写 出通用的代码.
–4,特点:
–前提: 发生继承关系 + 发生方法重写
–口诀: 父类引用指向子类对象 + 编译看左边运行看右边
–5,入门案例

	package cn.tedu.oop;
	//测试 多态
	public class Test4_Multi {
		public static void main(String[] args) {
			//TODO 创建子类对象测试
			Dog d = new Dog();
			d.eat();//重写了,用了子类的
			
			//TODO 创建多态对象测试
			//口诀1:父类引用 指向 子类对象-相当于把子类转成父类
			Animal a = new Dog();
			//口诀2:编译看左边,运行看右边
			a.eat();//使用了父类的方法声明,使用了子类的方法体
	//编译看左边 -- 是指 想要成功的保存,就要使用左边也就是  只能使用父类提供的功能!!
	//运行看右边 -- 是指 想要得到结果,就要看右边也就是  使用子类的方法体!!!
		}
	}
	class Animal{
		public void eat() {
			System.out.println("吃奥特曼");
		}
	}
	//1,多态的前提1:发生继承关系
	class Dog extends Animal{
		//2,多态的前提3:发生方法重写
		@Override
		public void eat() {
			System.out.println("狗吃屎");
		}
	}

多态的好处
–1,提高了程序的灵活性和扩展性
–2,多态中,根本不关心具体的子类的类型,可以屏蔽子类间的不同,把子类都当做父类对待
–3,代码更加通用,做出统一的编程
–4,代码体现:
class Test{
//现在的eat()具体的指定了要吃啥!!!太死板.
//怎么灵活?如果能够不关心具体是哪种小动物.
eat(Aniaml a){ }//多态,只要是小动物都能吃
eat(Dog a){ }//写死了,必须是小狗吃
eat(Cat a){ }//写死了,必须是小猫吃
eat(Tiger a){ }//写死了
eat(… a){ }//写死了
eat(… a){ }//写死了
}

多态的使用
–1,代码

	package cn.tedu.oop;
	//测试 使用多态
	//成员变量.成员方法.静态方法
	public class Test5_UseMulti {
		public static void main(String[] args) {
			//创建多态对象测试 -- //口诀1:父类引用 指向 子类对象
			Father f = new Son();
			//口诀2: 编译看左边(只能用父类提供的资源),运行看右边(结果只能以子类为准-针对重写方法)
			//1,多态对象使用的成员变量  --- 使用父类的10
			System.out.println( f.sum );
			//2,多态对象使用的成员方法  --- 使用了父类的方法声明,使用了子类的方法体
			f.study();
			//3,静态方法可以重写吗 --- 不可以!!
			f.show();//使用了父类的方法声明 和 方法体
			Father.show();//静态资源,谁调用就执行谁的功能,根本没有重写的说法!!
		}
	}
	class Father{
		int sum = 10 ;
		public void study() {
			System.out.println("学习养生");
		}
		static public void show() {
			System.out.println("Father...show()");
		}
	}
	class Son extends Father{
		int sum = 20 ;
		@Override
		public void study() {
			System.out.println("学习敲代码");
		}
		static public void show() {
			System.out.println("Son...show()");
		}
	}	

异常
–1,异常是指程序中出现的Bug.
–2,继承结构非常严谨,Throwable-Exception-…
–3,Exception是程序中所有异常的父类
–4,异常处理
–捕获:把程序中会出现的异常自己处理掉
try{
代码
}catch(异常类型1 异常名){
给出解决方案1
}catch(异常类型2 异常名){
给出解决方案2
}
–抛出:把程序中出现的异常自己不管,交给调用者去管
–5,测试

	package cn.tedu.oop;

	import java.util.InputMismatchException;
	import java.util.Scanner;

	//测试 异常
	public class Test6_Exception {
		public static void main(String[] args) {
	//		method() ; //暴露异常
			method2() ; //异常处理!!!--捕获异常
		}
		//捕获异常
		private static void method2() {
			try {//尝试执行try里的代码
				int a = new Scanner(System.in).nextInt();
				int b = new Scanner(System.in).nextInt();
				System.out.println(a/b);
			}catch(ArithmeticException a) {//如果分母为0了立刻捕获
				System.out.println("两次输入不能为0!");
			}catch(InputMismatchException a) {//如果类型不对了立刻捕获
				System.out.println("请输入两次整数!");
			}catch(Exception a) {//如果有其他异常立刻捕获
				//多态的好处:不关心具体的子类类型,把子类当父类来看。写出通用代码
				System.out.println("请输入正确的数据!");
			}
			//现在的问题是:程序中也许不仅仅只有两种异常,还可能有更多异常
			//但是,我根本不知道还有几个异常,异常的名字叫什么????
			
		}
		//暴露异常
		public static void method() {
			//接收键盘输入的两个整数
			int a = new Scanner(System.in).nextInt();
			int b = new Scanner(System.in).nextInt();
			//做除法运算
			System.out.println(a/b);
		}
	}

异常处理
–1,抛出:自己不处理,谁调用谁处理
–在方法声明上添加代码 ,如: throws 异常类型
–2,测试

	package cn.tedu.oop;

	import java.util.InputMismatchException;
	import java.util.Scanner;

	public class Test1_Exception {
	//	public static void main(String[] args) throws Exception{
		public static void main(String[] args){
	//		method();//暴露异常
			try {
				method2();
			}catch(Exception e){
				//3,method2抛出异常自己没管,调用者来处理抛出的异常Exception
				System.out.println("运算异常!!");
			}
		}
		//1,抛出异常--在方法声明上添加throws 异常类型1,异常类型2
		public static void method2() 
	//			     throws ArithmeticException,InputMismatchException,?, ?{
					 throws Exception{
					//2,多态,根本就不关心具体的异常类型,都会把子类当父类来看
			int a = new Scanner(System.in).nextInt();
			int b = new Scanner(System.in).nextInt();
			System.out.println(a/b);
		}
		//暴露异常
		public static void method() {
			//接收键盘输入的两个整数
			int a = new Scanner(System.in).nextInt();
			int b = new Scanner(System.in).nextInt();
			//做除法运算
			System.out.println(a/b);
		}
	}

抽象类
–1,子类继承了父类,就可以使用父类的eat().但是吃的不一样,也可以进行重写.改的是方法体…
–2,是一个特殊的方法,特殊在这个方法根本就没有方法体–抽象方法
–3,如果类里有抽象方法,那么这个类就是一个抽象类
–4,抽象类里面的方法 可以没有方法体
–5,入门案例

	package cn.tedu.oop;
	//测试 抽象类
	public class Test2_Abstract {
		public static void main(String[] args) {
			//7,抽象类多用于多态中
			Animal a = new Cat(); //口诀1:父类引用指向子类对象
			a.eat();//口诀2:编译看左边--功能向父类看齐,父类就是标准
			a.sleep();//运行看右边--针对方法重写--结果要看子类怎么干的
			
			//6, 抽象类不能被实例化
	//		Animal b = new Dog(); 
		}
	}
	//普通类,普通方法
	//3, 如果类里包含抽象方法 ,那么这个类就是一个抽象类
	abstract class Animal{
	//0,分析后,发现,如果子类继承父类后,吃的都不一样,肯定会发生修改发生方法重写的现象
	//方法体肯定会被修改,父类干脆也就不提供方法体了--变成了抽象方法
		//1,通过abstract关键字来描述抽象
		//2,抽象方法 只有方法声明 没有方法体
		abstract public void eat() ;
		//0,方法体不会被改,父类提供还是有意义的
		public void sleep() {
			System.out.println("呼呼大睡");
		}
	}
	//4,子类继承 抽象类以后,可以有两个选择:要么是一个抽象类 
	abstract class Dog extends Animal{
	}
	//5,子类继承 抽象类以后,可以有两个选择:要么把所有抽象方法都重写
	class Cat extends Animal{
		//abstract public void eat() ;
		@Override
		public void eat() {
			System.out.println("猫吃鱼");
		}
	}

抽象类的用法
–1,构造函数

	package cn.tedu.oop;
	//测试   抽象类使用构造方法
	//总结
	//3,抽象类里是可以有 构造方法的--干嘛用--不是为了让自己new,而是为了让子类new
	public class Test3_UseAbstract {
		public static void main(String[] args) {
			//一定会触发子类的构造方法
			new Dog2();
	//		new Animal2() ;
		}
	}
	//抽象类
	abstract class Animal2{
	//3,抽象类里是可以有 构造方法的--干嘛用--不是为了让自己new,而是为了让子类new
		public Animal2() {
			System.out.println("父类的 构造方法");
		}
	}
	class Dog2 extends Animal2{
		//1,子类有没有构造方法? -- 有一个默认的无参构造
		public Dog2() {
			//2,隐藏着super()--会去找父类的 无参构造
			super();
			System.out.println("子类的 构造方法");
		}
	}

–2,抽象类的成员变量

	package cn.tedu.oop;
	//测试   抽象类使用成员变量
	//总结
	//抽象类里可以有变量也可以有常量
	public class Test4_UseAbstract2 {
		public static void main(String[] args) {
			Animal3 a = new Dog3();
			a.name = "二哈" ;//变量可以修改值
			System.out.println(a.name);//变量可以获取值
			
	//		a.MAX_VLAUE = 126 ;//常量的值不可以被修改
			System.out.println(a.MAX_VLAUE);//常量可以直接获取值
		}
	}
	abstract class Animal3{
		//1,抽象类中 可以提供 变量
		String name = "大黄";
		//2,抽象类中 可以提供 常量
		public static final byte MAX_VLAUE = 127 ;
	}
	class Dog3 extends Animal3{
	}

–3, 抽象类的成员方法

	package cn.tedu.oop;
	//测试   抽象类使用成员方法
	public class Test5_UseAbstract3 {
		public static void main(String[] args) {
			//创建对象测试
			Animal4 a = new Dog4();
			a.sleep();//普通方法--重写前用父类的,重写后用子类的
			a.eat();//抽象方法--用了父类的方法声明,子类的方法体
			a.game();//抽象方法--用了父类的方法声明,子类的方法体
		}
	}
	//1,如果类里都是普通方法,这个类仍然被修饰成了抽象类,为什么?--抽象类不能实例化
	//2,抽象类是一个特殊的类,非常灵活.特殊在类里可以有抽象方法也可以有普通方法.
	abstract class Animal4{
		//普通方法--提供方法体
		/*
		 * public void eat() { System.out.println("eat()..."); }
		 * public void game() { System.out.println("game()..."); }
		 */
		public void sleep() {
			System.out.println("sleep()...");
		}
		//抽象方法--没有方法体
		abstract public void eat() ;
		abstract public void game() ;
	}
	//3,抽象类的子类,需要把所有抽象方法都重写,否则就是一个抽象类
	//而继承来的普通方法看需求,需要修改就重写不改也可以不重写
	class Dog4 extends Animal4{
		@Override
		public void eat() {
			System.out.println("eat()...");
		}
		@Override
		public void game() {
			System.out.println("game()...");
		}
	}
	//4,抽象类的子类,可以还是一个抽象类(因为包含着继承来的抽象方法)
	abstract class Cat4 extends Animal4{
		//Animal4里面有两个抽象方法,你只重写一部分的话,就说明还包含着没重写的抽象方法
		//还得是一个抽象类
	//	abstract public void eat() ;
	//	abstract public void game() ;
		@Override
		public void eat() {
			System.out.println("Cat4..eat()"); 
		}
	}

在这里插入图片描述
接口
–1,概念
–1,接口来的目的就是为了突破java单继承的局限性
–2,接口的好处:灵活,可以同时使用多个接口的功能
–3,接口主要体现的是 一套开发规范
–2,特点
1、 接口中都是抽象方法
2、 通过interface关键字创建接口
3、 通过implements让子类来实现
4、 可以理解成,接口是一个特殊的抽象类
5、 接口突破了java的单继承的局限性
6、 接口和类之间可以多实现,接口和接口之间可以多继承
7、 接口是对外暴露的规则,是一套开发规范
8、 接口提高了程序的功能扩展,降低了耦合性
–3,入门案例

	package cn.tedu.oop;
	//测试 接口
	public class Test1_Interface {
		public static void main(String[] args) {
			//TODO 创建多态对象测试
			//9,接口可以被实例化吗?--不可以,接口和抽象类一样都不能被实例化
	//		new Demo() ;
			
			//8,用了接口里的抽象方法的声明,实现类的方法体
			Demo demo = new DemoImpl();
			demo.eat();
			demo.game();
			demo.hi();
		}
	}
	//1,抽象类里可以有抽象方法(必须被abstract修饰),也可以有普通方法(提供方法体)
	//3,通过interface关键字定义接口,语法:interface 接口名
	interface Demo{
	//2,接口里的方法都是抽象方法
		abstract public void eat() ;
		abstract public void game() ;
		//4,在jdk1.8里允许接口中出现普通方法,要求被static或者default修饰
	//	static public void hi() {}
	//	default public void hi() {}
		
		//5,接口为方法的编写提供了简写方式,会自动拼接 public abstract 
	//	public abstract void hi() ;
		void hi() ;//简写形式
	}
	//6,如果想用接口里的功能,怎么用呢?--和接口发生实现关系
	//class Dog extends Animal{//继承时,是子类继承抽象类,来使用抽象类的功能
	class DemoImpl implements Demo{//现在是,实现类 实现 接口,来使用接口的功能
		//7,实现接口后,由于接口里都是抽象方法,所以需要全都重写,否则就是一个抽象类
		@Override
		public void hi() {
			System.out.println("hi()...");
		}
	    @Override
		public void eat() {
	    	System.out.println("eat()...");
		}
	    @Override
		public void game() {
			System.out.println("game()...");
		}
	}
	//abstract class DemoImpl implements Demo{//现在是,实现类 实现 接口,来使用接口的功能

接口的用法
–1,构造方法
–2,成员变量
–3,成员方法
–4,测试

	package cn.tedu.oop;
	//测试 接口
	//总结
	//接口里没有构造方法/没有变量都是常量
	//接口里都是抽象方法(jdk1.8可以有特殊的普通方法)
	//接口里的常量可以简写,会自动拼接public static final
	//接口里的方法可以简写,会自动拼接public abstract
	public class Test2_Interface2 {
		public static void main(String[] args) {
			//3,接口不能被实例化
			Inter in = new InterImpl();
			//in.age = 20; //修改值,失败---age是final的
			System.out.println( in.age );//获取值
			System.out.println( Inter.age );//获取值,age是static的
			
			//TODO 7,测试接口里的方法
			String desc = in.save();
			System.out.println(desc);
			
			in.delete(10);
		}
	}
	//0,通过interface定义接口
	interface Inter{
		//1,接口里不让出现构造方法.Interfaces cannot have constructors
	//	public Inter() { }
		//2,接口里没有变量!!! -- 会自动拼接public static final把变量变成常量!!
		//public static final int age = 10; 
		int age = 10 ; //简写形式
		//4,接口里的方法--会自动拼接public abstract 
	//	 public abstract void save() ;
	//	 public abstract void delete() ;
		String save() ;//简写形式
		void delete(int id) ;
	}
	//5,接口的实现类,要么重写所有抽象方法,要么是一个抽象类
	//abstract class InterImpl implements Inter{
	class InterImpl implements Inter{
		//6,在进行方法重写时,要有足够的权限.接口里的所有资源默认的权限都是public
		 @Override
		 public String save() {
			 return "保存成功!" ;
		 }
		 @Override
		 public void delete(int id) {
			 System.out.println("delete()..."+id);
		 }
	}

接口的复杂用法
–接口和类之间可以多实现,接口和接口之间可以多继承
–测试

	package cn.tedu.oop;

	import java.io.Reader;

	//测试 接口的复杂用法
	//接口和类之间可以多实现,接口和接口之间可以多继承
	public class Test3_Interface3 {
		public static void main(String[] args) {
			//4,--2号接口的功能,接口那么多,想用谁的功能,左边就写谁
			Inter2 in = new Inter2Impl() ;
			in.update();
			in.save();
			in.delete(5);
			in.get();
		}
	}	
	interface Inter1{
		void save();
	}
	interface Inter3{
		void update();
		void get();
	}
	//5,实现类可以在继承的同时,多实现
	abstract class Impl2 extends Object implements Inter1 , Inter3{
		
	}
	//3,接口和实现类之间 -- 是实现关系 ,可以多实现(逗号隔开)
	//--Impl实现类,同时实现了Inter1和Inter3接口的功能,
	//--需要同时重写多个抽象方法,否则就是一个抽象类
	class Impl implements Inter1 , Inter3{
		@Override
		public void update() {
		}
		@Override
		public void get() {
		}
		@Override
		public void save() {
		}
	}
	//1,接口和接口之间 -- 是继承关系,可以多继承(逗号隔开)
	//--2号接口同时使用了1号和3号接口的功能! 
	interface Inter2 extends Inter1 , Inter3{
		void delete(int id) ;
	}
	//2,想要使用2号接口的功能,找一个实现类来实现接口
	class Inter2Impl implements Inter2{
		@Override
		public void save() {
			System.out.println(1);
		}
		@Override
		public void update() {
			System.out.println(2);
		}
		@Override
		public void get() {
			System.out.println(3);
		}
		@Override
		public void delete(int id) {
			System.out.println(4);
		}
	}

接口和抽象类的区别
–1,类和类间的关系:是继承关系
–java里只支持单根继承
–class A extends B
–其中A是子类,B是父类.子类可以使用父类的所有功能
–方法的重写override:如果想要修改父类的原有功能,可以进行方法重写
–2,接口和接口间的关系:是继承关系
–接口的出现就是为了突破java单继承的局限性
–接口间可以多继承
–interface A extends B , C
–其中A是子接口,B和C是父接口
–A就拥有了B和C的所有功能,A的功能是最全的
–class Impl implements A
–Impl实现类就需要同时重写A B C 接口里的所有抽象方法,否则就是一个抽象类

–3,类和接口间的关系:是实现关系
–实现类可以实现接口,而且可以多实现
–class A implements B,C
–A是实现类,B和C是接口.
–A需要同时重写B和C接口里的所有抽象方法,否则就是一个抽象类
–类可以在继承的同时多实现
–class A extends B implements C , D
–A可以叫子类,也可以叫是实现类
–A同时拥有父类B的功能,也同时拥有接口C和D的功能
–A需要同时重写C和D接口里的所有抽象方法,否则就是一个抽象类
–对于父类B里的方法吗?看需求,B类是父类,里面如果都是普通方法,只有需要修改才会发生重写.

–4,抽象类和接口的区别
–相同点
–抽象类和接口都是抽象层,一般用来提取共性
–都不能被实例化
–不同点
–构造方法:抽象类里有,接口里没有!!
–成员变量:抽象类里有,接口里没有,接口里都是常量!!
–成员方法:抽象类类可以有普通方法和抽象方法,但是接口里都是抽象方法(1.8后可以有)
–接口里存在简写形式,抽象类里没有.
–接口里的常量,int age = 10;会为常量自动拼接public static final
–接口里的方法,void save();会为方法自动拼接public abstract
–怎么去设计你的抽象层,到底是体现为一个抽象类呢还是接口呢?
–关键就看你需不需要提供方法体,如果类里的方法都不需要提供方法体,可以设计为接口.如果类里的方法需要提供方法,设计为抽象类.
–抽象层到底设计成抽象类还是接口,谁好呢?
–如果实现类想要同时拥有多个功能,最好选择接口,因为接口可以多继承多实现
–如果就是设计为抽象类,子类就只能继承一个父类,只有这么一次的继承权

在这里插入图片描述
在这里插入图片描述
设计模式

Java中有23 种设计模式,本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解。

当然,软件设计模式只是一个引导,在实际的软件开发中,必须根据具体的需求来选择。

1、 对于简单的程序,可能写一个简单的算法要比引入某种设计模式更加容易。

2、 但是对于大型项目开发或者框架设计,用设计模式来组织代码显然更好。

单例设计模式概念

单例模式可以说是大多数开发人员在实际中使用最多的,常见的Spring默认创建的bean就是单例模式的。

单例模式有很多好处,比如可节约系统内存空间,控制资源的使用。

其中单例模式最重要的是确保对象只有一个。

简单来说,保证一个类在内存中的对象就一个。

RunTime就是典型的单例设计,我们通过对RunTime类的分析,一窥究竟。

源码剖析

/**

 * Every Java application has a single instance of class

 * <code>Runtime</code> that allows the application to interface with

 * the environment in which the application is running. The current

 * runtime can be obtained from the <code>getRuntime</code> method.

 * <p>

 * An application cannot create its own instance of this class.

 *

 * @author  unascribed

 * @see     java.lang.Runtime#getRuntime()

 * @since   JDK1.0

 */

RunTime.java

package java.lang;

public class Runtime {

   //1、创建静态的全局唯一的对象

   private static Runtime currentRuntime = new Runtime();

    //2、私有构造方法, 

    /** Don't let anyone else instantiate this class */

    private Runtime() {}
	//3、通过自定义的静态方法获取实例
 

    public static Runtime getRuntime() {

        return currentRuntime;

    }

}

饿汉式

目的:控制外界创建对象的个数只能创建1个对象

开发步骤:

1、 私有化构造方法

2、 在类的内部创建好对象

3、 对外界提供一个公共的get(),返回一个已经准备好的对象

package cn.tedu.single;

//测试单例设计模式  

public class Test8_Single {

public static void main(String[] args) {

   Single s = Single.get();

   Single s1 = Single.get();

   

   //get()多少次,内存中使用的都是同一个对象

   System.out.println(s);//cn.tedu.single.Single@15db9742

   System.out.println(s1);//cn.tedu.single.Single@15db9742

   }
}


class Single{

//  1、私有化构造方法,不让外界直接new

private Single() {}



//  2、在类的内部,创建好对象

//static :静态只能调用静态

static private  Single s = new Single();



//  3、对外界提供一个公共的get(),返回一个已经准备好的对象

//static是为了外界不通过对象访问而是通过类名直接方法  

static public Single get(){

   //注意:静态只能调用静态

   return s;

    }

}

懒汉式

class Single{

//  1、私有化构造方法,不让外界直接new

private Single() {}



//  2、在类的内部,创建好对象

//static :静态只能调用静态

static private  Single s = null;



//  3、对外界提供一个公共的get(),返回一个已经准备好的对象

//static是为了外界不通过对象访问而是通过类名直接方法  

synchronized  static public Single get(){

   //注意:静态只能调用静态

   if(s==null){

       s = new Single();//会有安全问题

}

   return s;

    }

}

abstract注意事项

抽象方法要求子类继承后必须重写。那么,abstract关键字不可以和哪些关键字一起使用呢?以下关键字,在抽象类中。用是可以用的,只是没有意义了。

1、 private:被私有化后,子类无法重写,与abstract相违背。

2、 static:静态的,优先于对象存在。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。

3、 final:被final修饰后,无法重写,与abstract相违背。

接口和抽象类的区别

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

2、抽象类要被子类继承,接口要被类实现。

3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果

7、抽象类里可以没有抽象方法,如果要扩展抽象类的新方法,子类将很容易的就能得到这些新方法。

8、如果一个类里有抽象方法,那么这个类只能是抽象类

9、抽象方法要被实现,所以不能是静态的,也不能是私有的。

10、接口可继承接口,并可多继承接口,但类只能单根继承。

了解软件设计的开闭原则OCP

开放功能扩展,关闭源码修改。等

开闭原则的英文全称是Open Close Principle,缩写是OCP,它是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。

开闭原则的定义是:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。

开闭原则,是一种设计模式,随着面向对象程序设计的思想,应运而生。

开:指的是可以在源代码的基础上进行扩展,比如继承,接口,抽象类等。在JAVA中,之所以用继承,是在可以直接调用类库的前提下,对其功能进行扩展。不需要应用者去了解封装类的内部逻辑就可以做开发。

闭:指不允许对原有的代码进行修改。以免影响其他现有功能,造成功能瘫痪。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值