java基础2 面向对象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()...");
			}
		}

类和对象的创建和使用

	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 );//10.9 
				System.out.println( c.peizhi );//高
				System.out.println( c.color );//black"
				System.out.println( c.model );//X6
			}
		}
		//使用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()...");
			}
		}

封装:

--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,练习1:构造方法创建对象

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+"岁.");
			}
		}

构造方法赋值:

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,练习1:当变量名相同时

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
			}
		}

构造方法间的调用:

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("子类的 构造方法");
			}
		}


,抽象类的成员变量

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
            --怎么去设计你的抽象层,到底是体现为一个抽象类呢还是接口呢?
                --关键就看你需不需要提供方法体,如果类里的方法都不需要提供方法体,可以设计为接口.如果类里的方法需要提供方法,设计为抽象类.
            --抽象层到底设计成抽象类还是接口,谁好呢?
                --如果实现类想要同时拥有多个功能,最好选择接口,因为接口可以多继承多实现
                --如果就是设计为抽象类,子类就只能继承一个父类,只有这么一次的继承权

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值