Java基础知识总结(6-10)

一、day06—面向对象1

1、面向对象

所谓的面向对象是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的执行者变成了指挥者,面向对象是基于面向过程而言的。

我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)

  • 三大特征

    • 封装性,把相关的数据封装成一个“类”组件
    • 继承性,是子类自动共享父类属性和方法,这是类之间的一种关系
    • 多态,增强软件的灵活性和重用性

    如果说四大特征:就加上抽象

  • 类和对象的关系

    类是对象的抽象,对象是类的实例。类是抽象的,不占用内存,而对象的类的实例,是占存储空间的。类就是创建对象的蓝图,好比建筑设计图纸和建筑之间的关系。

对象内存图

--1,测试Phone
			package cn.tedu.oop;
			//注意:一个.java文件中,可以存在多个类.
			//只不过只能有一个类被public修饰,并且这个public的类名就是.java文件的文件名
			public class Test2_Class {
				public static void main(String[] args) {
					//2,通过new关键字,创建对象
			//		new Phone().call();//匿名对象--一次只干一个活儿
					//3,p是引用类型的变量,保存了对象在内存中的地址值
					Phone  p = new Phone();
					System.out.println(p);//cn.tedu.oop.Phone@15db9742
					//4,调用模板里的功能
					p.call();
					p.message();
					p.music();
					//设置属性的值
					p.color = "red" ;
					p.size = 5.7 ;
					p.pinpai = "HUAWEI" ;
					p.price = 5899 ;
					//获取属性的值
					System.out.println(p.color);
					System.out.println(p.size);
					System.out.println(p.pinpai);
					System.out.println(p.price);
				}
			}
			//1,通过class关键字,创建手机类--抽象的--来描述生活中的手机事物
			class Phone{
				//特征--成员变量/属性
				String color;//颜色
				double size; //尺寸
				String pinpai;//品牌
				int price ;//价格
				//行为--成员方法
				//修饰符 返回值 方法名(参数列表){方法体}
				public void call() {//打电话
					System.out.println("call()...");
				}
				public void message() {//发短信
					System.out.println("message()...");
				}
				public void music() {//听音乐
					System.out.println("music()...");
				}
			}
2、封装
--1,通过private关键,实现封装
	是一个权限修饰符,用于修饰成员变量和成员函数,被私有化的成员只能在本类中访问。
	想要修改只能,对外提供公共的,get和set方法
--2,为了提高程序的安全性,不让外界随意获取或者修改
//测试 封装
		public class Test4_Private {
			public static void main(String[] args) {
				//创建Student对象测试
				Student s = new Student();
				//设置属性值
		//		s.name = "董长虫" ; 被private了,只能在自己类中可见
		//6,调用set方法完成间接赋值,把实参拿到以后直接给name属性赋值成功
				s.setName("长虫");
				
				s.age = 33 ;
				s.gender = '女' ;
				//获取属性值
				//2,被private了,只能在自己类中可见
		//		System.out.println( s.name ); 
				//4,访问公共的get(),间接获取name属性的值
		//		String name = s.getName() ;
		//		System.out.println(name);
				System.out.println( s.getName() );//长虫
				System.out.println( s.age );
				System.out.println( s.gender );
			}
		}
		//提供Student类
		class Student{
			//1,通过private关键字,实现封装.只能在本类中可用
			private String name ;
			//3,提供公共的获取方式--getXxx()--目的是返回属性的值
			public String getName(){ 
				return name ;//把name属性的值返回给外界调用位置
			}
			//5,提供公共的修改方式--setXxx()--目的是设置属性的值
			public void setName(String n){
				name = n ; //拿到你设置的n的值,给name属性赋值
			}
			
			//TODO 封装以下属性,并测试
			int age; //0
			char gender ;//\u0000
			String addr;
			double score ;
			
			//行为
			public void coding() {
				System.out.println("coding()...");
			}
			public void eat() {
				System.out.println("eat()...");
			}
		}

二、day07—面向对象2

1、构造方法
--1,概述
		--创建对象时会自动调用构造方法
	    --构造方法和其他方法一样也可以重载
		--作用:完成对象的创建或者完成对象的初始化
--2,语法:
		--普通方法:修饰词 返回值 方法名(参数列表){方法体}
	  	--构造方法:修饰符 类名(参数列表){方法体}

–3,构造方法完成创建对象

//测试 构造方法Constructor / 构造器
		//总结
		//1,触发的时间节点:构造方法摆在那儿不会主动执行,需要new来触发
		//2,构造方法可以重载,为了方便各种new,体现程序的灵活性
		//3,构造方法在创建对象时,会自动执行
		public class Test1_Constructor {
			public static void main(String[] args) {
				//创建对象测试
				new Student("1",2);//触发了public Student(String a,int b) 
				new Student();//触发无参构造
				new Student("1");//触发了public Student(String name) 
				new Student(1);//触发了public Student(int a) 
				new Student(1,2);//触发了public Student(int a,int b)
			}
		}
		//创建Student类
		class Student{
			public Student(String a,int b) {
				System.out.println("含参构造,名字是:"+a+",年龄是:"+b);
			}
			//1,提供构造方法:修饰符 类名(参数列表){方法体}
			//5,默认就会存在无参构造--前提是.不能只提供含参的构造方法
			public Student() { }
			//3,重载-- 在同一个类里,方法名相同,但是参数列表不同
			public Student(String name) {
				System.out.println("含参构造方法"+name);
			}
			public Student(int a) {
				System.out.println("含参构造方法"+a);
			}
			public Student(int a,int b) {
				System.out.println("含参构造方法"+a+b);
			}
		}
2、代码块

​ --1,概述
​ --被花括号包起来的一段代码就叫代码块
​ --代码块的位置不同,作用用法名字都不同
​ --2,构造代码块
​ --成员位置(类里方法外)的代码块叫构造代码块
​ --作用:通常用于抽取构造方法中的共性代码
​ --顺序:new时,先调用构造代码块,然后调用构造方法,优先于构造方法加载
​ --3,局部代码块
​ --局部位置(方法里)的代码块叫局部代码块
​ --作用:通常用于控制变量的作用范围

/测试 代码块
		//总结
		//1,创建对象时:本来是只会触发构造方法,但是,如果有构造代码块,就会先触发构造代码块再执行构造方法
		//2,调用方法时:顺序执行方法里的代码,如果有局部代码块也就一起执行
		//3,执行顺序:new时--构造代码块>构造方法,调用方法时--局部代码块
		//4,构造代码块--用来提取构造方法的共性--new时才触发
		//5,局部代码块--用来控制变量的作用范围--调用方法时才触发
		public class Test3_Block {
			public static void main(String[] args) {
				new Person().show();//触发无参构造
				new Person("熊大");//触发含参构造
			}
		}
		//创建Person类
		class Person{
		//1,构造代码块:位置是在成员位置--触发节点是 new时--先执行构造代码块再执行构造方法
		//--作用:抽取构造方法的共性
			int age ;
			{
				age = 0 ;//提取了所有构造方法的共性功能
				System.out.println("构造代码块");
			}
			public Person() {
				System.out.println("无参构造方法"+age);
			}
			public Person(String name) {
				System.out.println("含参构造方法"+name+age);
			}
			//2,局部代码块:位置是在方法里--触发节点是 当方法被调用时--用来控制变量的作用范围
			public void show() {
				{
					int x = 10;
					System.out.println(x);
					System.out.println("局部代码块");
				}
			}
		}

3、this关键字

​ --1,代表本类对象的一个引用对象
​ --2,作用:
​ --用来区分同名的成员变量和局部变量
​ --用来完成构造方法间互相调用

//测试 this关键字
		//总结
		//当局部变量名  和  成员变量名  相同时,需要用this调用 成员变量
		public class Test4_This {
			public static void main(String[] args) {
				//通过对象,来访问类里的成员(成员变量和成员方法)
				new Demo().test();
		//		Demo d = new Demo() ;
		//		System.out.println( d.name );
				System.out.println( new Demo().name );
			}
		}	
		//创建Demo类
		class Demo{
			String name ;
			int count = 20 ;//成员变量
			
			public void test() {
				int count = 10;//局部变量
				System.out.println(count);//变量的就近原则,会使用局部变量 的值 10
				System.out.println(name);//成员变量
				//1,想要使用  和  局部变量 同名的 成员变量count--this调用成员变量
		//this表示的是本类的对象的引用--底层帮你new了一个本类对象--Demo this = new Demo();
				System.out.println( this.count );//20,成员变量
			}
		}
//测试   this--用来完成 构造方法间 互相调用
		//总结
		//1,如果在构造方法间,互相调用时,this不能省略
		//2,位置必须是第一条语句
		public class Test5_This2 {
			public static void main(String[] args) {
		//		new Demo2();
				new Demo2(1);
			}
		}
		class Demo2{
			 public Demo2() {
				 //1,在 无参构造里  调用 含参构造
		//		 this(10);
				 System.out.println("无参构造");
			 }
			 public Demo2(int a) {
				 //2,在 含参构造里  调用 无参构造
				 this();//3,在构造方法中,使用this关键字,必须是第一条语句
				 System.out.println("含参构造"+a);
			 }
		}
4、继承

​ --1,概述
​ Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数 据或新 的功能,也可以用父类的功 能,但不能选择性地继承父类/超类/基类。
​ --2,好处
​ 提高父类代码的复用性,减少子类代码的编写,提高开发效率
​ --3,特点
​ --使用extends关键字
​ --相当于子类把父类的功能复制了一份
​ --java只支持单继承
​ --继承可以传递(爷爷,儿子,孙子的关系)
​ --不能继承父类的私有成员
​ --继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展
​ --像是is a 的关系

4、测试继承

//测试 继承	
		public class Test6_Extends {
			public static void main(String[] args) {
				//创建Dog对象测试
				new Dog().eat();
				new Dog().sleep();
				System.out.println( new Dog().name );
			}
		}
		class God{
			String name ;
		}
		//1,父类来了--提取子类的共性--提高了代码的复用性
		class Animal extends God{
			//5,父类的私有成员(成员变量/成员方法)不能被继承
			private double sifangmoney = 100 ;
			
			public void eat() {
				System.out.println("啥都吃");
			}
		}
		//2,子类想拥有父类的功能--需要发生继承关系
		class Dog extends Animal{//4,java只支持单继承
			//3,相当于子类把父类的功能复制了一份
			//6,除了能用父类继承来的,还可以自己做扩展java
			public void sleep() {
				System.out.println("sleep()..");
			}
		}
		class Cat{
		}

–5,super关键字
–1,在子类中用,用来访问父类的成员(成员变量/成员方法)
–2,super表示父类对象的引用,底层自动创建了一个父类的对象
–3,如果在构造方法里使用super关键字,位置上必须是第一条语句
–6,方法的重写override
–1,重写的前提是:发生继承关系+子类的方法声明和父类一样
–2,啥时候需要重写?–想要改,改掉父类原来的实现时

内存结构继承图

5、this和super的区别

1、 this代表本类对象的引用,super代表父类对象的引用。

2、 this用于区分局部变量和成员变量

3、 super用于区分本类变量和父类变量

4、 this.成员变量 this.成员方法() this(【参数】)代表调用本类内容

5、 super.成员变量 super.成员方法() super(【参数】),代表调用父类内容

6、 this和super不可以同时出现在同一个构造方法里,他们两个只要出现都得放在第一行,同时出现的话,到底第一行放谁呢。

6、 重载与重写的区别(Overload和Override的区别)

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分

三、day08—面向对象3

1、static关键字

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

测试:

//测试 静态关键字
		//总结:
		//1,静态的调用关系---静态只能调用静态--非静态调用啥资源都可以
		//2,静态资源是加载非常早的,随着类的加载就已经加载进内存了,比对象早
		//3,静态资源的访问方式:通过对象调用 + 通过类名调用
		public class Test4_Static {
			public static void main(String[] args) {
		//2,静态资源优先于对象加载,因为是随着类的加载就已经加载了
				Student.coding();
				System.out.println(Student.name);
				
				Student s = new Student();
				s.study();
				System.out.println(s.age);
				
		//1,静态资源,多了一种访问方式,除了可以用对象访问,更提倡用类名直接调用
		//		s.coding();
		//		System.out.println(s.name);
				Student.coding();
				System.out.println(Student.name);
				
				//3,静态资源是共享资源,能够被多个对象共享
				Student s1 = new Student();
				s1.name="陈子枢";
				
				Student s2 = new Student();
				System.out.println(s2.name);//陈子枢
			}
		}
		class Student{
			//普通资源 
			int age = 10;
			public void study() {
				//6,非静态调用关系? -- 调用任意资源
				System.out.println(age);
				System.out.println(name);
				coding();
				System.out.println("正在学习java");
			}
			//静态资源
			static String name ;
			static public void coding()  {
				//4,静态资源里,不能使用this或者super关键字!
		//		this.study();
		//		super.
				//5,静态调用关系? -- 只能调用静态,不能调用非静态的
				System.out.println(name);
		//		study();
				System.out.println("正在敲代码");
			}
		}

static修饰的方法不能被重写可以被继承

public class StaticLearnig {
    public static void main(String[] args) {
        SuperClass superClass=new SubClass();
        superClass.a();
        superClass.b();
    }
}
/*
结果:
SuperClass a
SubClass b
*/

class SuperClass{
    //静态方法
    public static void a(){
        System.out.println("SuperClass a");
    }
    //非静态方法
    public void b(){
        System.out.println("SuperClass b");
    }

}

class SubClass extends SuperClass{
    //静态方法
    public static void a(){
        System.out.println("SubClass a");
    }

    //非静态方法
    public void b(){
        System.out.println("SubClass b");
    }
}

静态的方法可以被继承,但是不能重写。如果父类中有一个静态的方法,子类也有一个与其方法名,参数类型,参数个数都一样的方法,并且也有static关键字修饰,那么该子类的方法会把原来继承过来的父类的方法隐藏,而不是重写。通俗的讲就是父类的方法和子类的方法是两个没有关系的方法,具体调用哪一个方法是看是哪个对象的引用;这种父子类方法不在存在多态的性质。

静态方法内存图:

img

2、static代码块

1、 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化

2、 构造代码块:在调用构造方法前会自动调用,每次创建对象都会被调用

3、 局部代码块:方法里的代码块,方法被调用时才会执行

4、 静态代码块:static{ },位置:在类里方法外

5、 TODO创建测试类,类中写好静态代码块,构造代码块,构造方法,普通方法里嵌套局部代码块。测试他们的执行顺序。

6、 静态 - 构造代码块 - 构造方法 - 局部

//测试 代码块
		//1,静态代码块:用来初始化项目--位置在成员位置
		//2,执行顺序:
		//类加载时 :   静态代码块
		//实例化时 :   构造代码块 > 构造方法
		//方法调用时 : 局部代码块
		public class Test5_Block {
			public static void main(String[] args) {
				StaticDemo s = new StaticDemo();//先执行构造代码块然后执行构造方法
				s.show();//执行局部代码块
				
				StaticDemo s2 = new StaticDemo();
			}
		}
		class StaticDemo{
			//静态代码块--位置也是在成员位置--用来完成项目的初始化
			//--只加载一次,在类第一次被加载时就跟着一起加载了(类的资源)
			static{
				System.out.println("静态代码块");
			}
			
			//构造代码块--位置是在成员位置--用来提取构造方法的共性
			{
				System.out.println("构造代码块");
			}
			//构造方法
			public StaticDemo() {
				System.out.println("构造方法");
			}
			//局部代码块--位置是在方法里--用来控制变量的作用范围
			public void show() {
				{	
					System.out.println("局部代码块");
				}
			}
		}
3、final关键字

1、 被final修饰的类,不能被继承

2、 被final修饰的方法,不能被重写

3、 被final修饰的变量是个常量,值不能被更改

4、 常量的定义形式: final 数据类型 常量名 = 值

让子类的重写权限变得可控.如果父类的某个方法不让子类重写,可以用final修饰变成最终方法

//测试 final关键字
		//1,final 修饰的类是最终的类,不能被继承
		//2,final 修饰的变量,是一个最终的变量,值不能被修改,称之为是常量
		//3,final 修饰的方法,不能被重写
		public class Test6_Final {
			public static void main(String[] args) {
				//创建子类对象测试
				Son s = new Son();
				s.eat();
		//		s.sum = 20 ;//final前可以改也能使用
				System.out.println(s.SUM);
			}
		}
		//1,final修饰的类是最终的类,不能被继承--The type Son cannot subclass the final class Father
		//final class Father{
		class Father {
		//3,final 修饰的变量,final用来修饰常量--The final field Father.sum cannot be assigned
		//	final int sum  = 10 ;
			static final int SUM  = 10 ;
		//2,final 修饰的方法,只能用不能被重写--Cannot override the final method from Father
			final public void eat() {
				System.out.println("Father...eat()");
			}
		}
		class Son extends Father{
		//	//想要改,发生了重写!!
		//	public void eat() {
		//		System.out.println("Son...eat()");
		//	}
		}
4、多态

1,就是指同一个对象,在不同时刻,代表的对象不同.就是指同一个对象的多种形态.
2,多态的作用 – 用来统一调用标准!!! 一切向父类看齐
3,好处是 : 做出通用编程,本质上就是不关心具体的子类的类型,屏蔽了子类之间的不同,可以把子类当做父类来看.
4,特点
–前提: 继承关系 + 方法的重

//测试 	多态
		public class Test7_Multi {
			public static void main(String[] args) {
				//创建子类对象测试
				new Dog().eat();//重写前执行父类的,重写后执行子类的
				//创建多态对象测试
				Animal a = new Dog();//口诀1:父类引用 指向 子类对象
				//口诀2:编译看左边,运行看右边 
				//编译看左边--是指想要保存成功,向左边也就是  向父类看齐--统一标准!!
				//运行看右边--是指结果向右边看齐也就是看子类的干活结果
				a.eat();//狗吃肉
		//		a.test();//test()是子类的特有方法,多态对象只能调用 父类的
			}
		}
		class Animal{
			public void eat() {
				System.out.println("啥都吃");
			}
		}
		//1,多态的前提:继承 + 方法重写(方法声明和父类一样)
		class Dog extends Animal{
			public void eat() {
				System.out.println("狗吃肉");
			}
			public void test() {
				System.out.println("test...");
			}
		}
5、多态的使用

–1,成员变量
–2,成员方法
–3,静态成员

–4,测试

//测试 	多态的使用
		//总结
		//1,多态中,的成员变量 --  用父类的
		//2,多态中,的成员方法 --  用父类的方法声明,用子类的方法体
		//TODO 3,多态中 ,的 静态资源?
		public class Test8_UseMulti {
			public static void main(String[] args) {
				//创建多态对象--父类引用 指向 子类对象
				Fu4 fu = new Zi4();
				//编译看左边,运行看右边
				System.out.println( fu.name );//成员变量用谁的?--父类的
				//多态中,方法声明用--父类的 ,方法体用--子类的(因为重写了)
				fu.show();//成员方法用谁的?--子类的(重写了)
				fu.test();//成员方法用谁的?--父类的(没重写)
			}
		}
		class Fu4{
			String name = "尼古拉斯.赵四" ;
			public void show() {
				System.out.println("Fu4...show()");
			}
			final public void test() {//被final了,不让子类重写了!
				System.out.println("Fu4...test()");
			}
		}
		class Zi4 extends Fu4{
			String name = "Anglelababa";
			public void show() {
				System.out.println("Zi4...show()");
			}
		}
6、向上转型和向下转型

在JAVA中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。

在应用中就存在着两种转型方式,分别是:向上转型和向下转型。

比如:父类Parent,子类Child

向上转型:父类的引用指向子类对象Parent p=new Child();

说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类的方法就根据这个引用指向调用子类重写方法。

向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。

Parent p = new Child();//向上转型,此时,p是Parent类型

Child c = (Child)p;//此时,把Parent类型的p转成小类型Child

//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的

说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。

四、day09—面向对象4

1、异常
  • 异常继承结构:

image-20200815113238319

  • 异常处理

–当一段代码出现异常时,可以有两种解决方案:捕获和抛出
–捕获:自己处理异常,别人调用就没有后患–推荐
–语法:把有问题的代码包起来
try{
代码
代码
代码
}catch(异常类型1 异常名){
合理的解决方案1
}catch(异常类型2 异常名){
合理的解决方案2
}catch(异常类型3 异常名){
合理的解决方案3
}
–抛出:自己不处理,交给调用者处理
–语法:
在方法声明上加 throws 异常类型
例:main() throws InputMismatchException

  • 测试
import java.util.InputMismatchException;
		import java.util.Scanner;
		//测试 异常
		public class Test1_Exception {
			public static void main(String[] args){
		//		method();//暴露异常
		//		method2();//捕获异常
				try {
			//调用了抛出异常的method3(),需要处理,捕获或者抛出二选一
					method3();//抛出异常
				}catch(Exception e) {
					System.out.println("运算错误!");
				}
			}
			/* 抛出异常
			 * 在方法声明上加 throws 异常类型1,异常类型2...
			 */
			public static void method3() 
		//				throws ArithmeticException,InputMismatchException{
						//多态,Exception体现了程序的通用性,可以把所有异常抛出去
						throws Exception{
				int a = new Scanner(System.in).nextInt();
				int b = new Scanner(System.in).nextInt();
				System.out.println(a/b);
			}
			/* 捕获异常
			 * try{ 代码... }catch(异常类型 异常名){ 合理的解决方案 }
			 * 异常类型: ArithmeticException  /  InputMismatchException
			 */
			public static void method2() {
				try {
					int a = new Scanner(System.in).nextInt();
					int b = new Scanner(System.in).nextInt();
					System.out.println(a/b);
				}catch(InputMismatchException a) {
					System.out.println("请输入两次整数!");
				}catch(ArithmeticException a) {
					System.out.println("第二次输入的整数不能为0 !");
				}catch(Exception a) {
		//怎么捕获其他的所有异常呢?--多态--通用性强-不关心子类类型,把子类当做父类来看
		//所有Exception的子类都能被捕获!
					System.out.println("请输入正确的数据!!");
				}
				
			}
			//暴露异常
			public static void method() {
				//1,接收键盘输入的两个整数
				int a = new Scanner(System.in).nextInt();
				int b = new Scanner(System.in).nextInt();
				//2,做除法运算
				System.out.println(a/b);
			}
			
		}
2、访问控制符

类的访问权限:

public:公共的,能被同个项目中的所有类访问(“必须和文件名相同”)

default:默认的,可被同个包中的类访问。

成员(成员变量或者成员方法)的访问权限

public:公共的,能被同个项目中的所有类访问。

protected:受保护的,能够被自己本身访问,能够被同个包中的所有类访问,能够 被自己的子类(不在同个包也可以)访问。

default:默认的,能够被自己访问,能够被自己同个包中的其他类访问。

private:私有的,能够被自己访问。

//测试 方法重写
		//四种修饰符,关系:public > protected > default > private 
		public class Test2_Override {
			public static void main(String[] args) {
			}
		}
		class Animal{
			void eat() {//是默认修饰符 default
				System.out.println("啥都吃");
			}
		}
		class Dog extends Animal{
			//方法重写时,要求子类的方法声明(返回值 方法名(参数列表))和父类一样
			//1,要求方法重写时,要有足够的权限.子类的重写权限>=原有权限
			public void eat() {
				System.out.println("只吃肉");
			}
		}
3、抽象类

–1,概述
Java中可以定义没有方法体的方法,该方法由其子类来具体的实现。该没有方法体的方法我们称之为抽 象方法,含有抽象方法的类我们称之为抽象类。
–2,特点
–通过java关键字abstract实现
–可以修饰方法或者类
–抽象类中可以没有抽象方法(由子类去实现)
–如果类中有抽象方法,那该类必须定义为一个抽象类
–子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写
–多用于多态中
–抽象类不可以被实例化

3,测试:

import java.io.IOException;
		import java.io.Reader;
		//测试 抽象类
		public class Test3_Abstract {
			public static void main(String[] args) {
				//创建多态对象--父类引用 指向 子类对象
		//		Animal2 a = new Dog2();//8,抽象类不能被实例化
				Animal2 a = new Cat2();
				a.eat();//父类的方法声明,父类的方法体
				a.sleep();//父类的方法声明,子类的方法体(重写了)
			}
		}
		//1,为什么产生父类?--为了提取子类的共性,提高父类代码的复用性
		//2,怎么优化父类?--程序设计--父类有没有可以省略的功能--方法体可以省略
		//4,如果类里包含抽象方法,那么,这个类就是一个抽象类
		//5,使用abstract关键字描述抽象
		abstract class Animal2{
			public void eat() {
				System.out.println("Animal...eat()");
			}
		//3,如果方法体,写了也要被修改,那就可以省略不提供--没有方法体的方法--抽象方法
			abstract public void sleep() ;
		}
		//6,子类继承抽象类后,就继承来了抽象方法,是一个 抽象的 子类
		abstract class Dog2 extends Animal2 {
			
		}
		//7,子类继承抽象类后,子类可以重写 所有的 抽象方法
		class Cat2 extends Animal2 {
		//	abstract public void sleep() ;
			@Override//注解,作用是用来标志这个方法是一个重写方法
			public void sleep() {
				System.out.println("猫吃鱼");
			}
		}
		//要么重写 所有的 抽象方法,要么就是一个抽象类
		//abstract class SubReader extends Reader{
		class SubReader extends Reader{
			//抽象方法必须重写,否则就是一个抽象类
			//普通方法不是必须重写,而是要改才重写
		//	abstract public void close() throws IOException;
			 public void close() throws IOException{
				 System.out.println("close() ");
			 }
			
		//	 abstract public int read(char cbuf[], int off, int len) throws IOException;
			 public int read(char cbuf[], int off, int len) throws IOException{
				 System.out.println("read() ");
				 return 0 ;
			 }
			 
		}
4、使用抽象类
--构造方法
			//测试 抽象类的 构造方法
			//总结
			//1,抽象类 里  有构造方法
			//2,抽象类自己不能被实例化,仍然会提供构造方法,因为方便子类new
			//3,当创建子类对象时,会触发子类的构造方法,子类的构造方法里第一条默认就会有super()
			//4,构造方法的执行顺序: 父类的 > 子类的
			public class Test4_Abstract2 {
				public static void main(String[] args) {
					//2,先执行父类的 构造方法 ,再执行自己的构造方法
					Animal3 a = new Dog3();
				}
			}
			//创建抽象类 
			abstract class Animal3{
			//3,抽象类不能被实例化,为什么还要提供构造方法?--为了方便子类new
				public Animal3() {
					System.out.println("Animal3..无参构造");
				}
			}
			class Dog3 extends Animal3{
				public Dog3() {
					super();//1,默认就存在,会主动找父类的无参构造
					System.out.println("Dog3..无参构造");
				}
			}


		--成员变量
			//测试 抽象类的 成员变量
			//总结
			//1,抽象类里可以有变量 也可以有常量
			//2,常量的值不能被修改,final的资源可以被继承但是不能被修改
			public class Test5_Abstract3 {
				public static void main(String[] args) {
					System.out.println( new Demo2().age );
					
			//		new Demo2().name = "123" ;final的常量,值不能被修改
					System.out.println( new Demo2().name );
				}
			}
			abstract class Demo{
				
				int age = 10 ;
				final String name = "Demo";
				
			}
			class Demo2 extends Demo{
				
			}
		--成员方法
			//测试 抽象类的 成员方法
			//总结
			//1,抽象类里可以都是抽象方法,要求子类重写 所有的 抽象方法,否则就是一个抽象的子类
			//2,抽象类里可以都是普通方法,目的是不让外界实例化
			//3,抽象类里包含抽象方法和普通方法,要求子类,重写 所有的 抽象方法,否则就是一个抽象的子类
			//4,抽象类是一个特殊的类,特殊在 抽象类里可以有抽象方法
			//5,抽象类的方法到底设计成普通方法还是抽象方法呢? -- 看方法体
			public class Test6_Abstract4 {
				public static void main(String[] args) {
					Demo3 d = new Demo5();//Demo3 Demo4都是抽象类不能new
					d.save();//多态的目的是统一标准,一切向父类看齐
					d.delete(10);
					d.update("jack");
				}
			}
			//1,抽象类是一个特殊的类,特殊在 类里可以有普通方法和 抽象方法
			//怎么决定类里的方法到底设计成普通方法还是抽象方法呢?--看方法体有没有必要提供
			abstract class Demo3{
				public void save() {
					System.out.println("数据保存成功!");
				}
				abstract public void delete(int id) ;
				abstract public void update(String name) ;
			}
			//2,子类继承了抽象类,只重写了一部分抽象方法,
			//也就是还包含着抽象方法,所以仍然是一个抽象类
			abstract class Demo4 extends Demo3{
			//	abstract public void delete(int id) ;
				 public void delete(int id) {
					 System.out.println("delete().."+id);
				 }
			}
			class Demo5 extends Demo4{
			//	abstract public void update(String name) ;
				public void update(String name) {
					System.out.println("update().."+name);
				}
			}

五、day10—面向对象5

1、接口

–1,概述
–接口的产生,是为了突破java单继承的局限性
–提倡面向接口,面向抽象编程
–是指把抽象层,修饰成接口或者抽象类
–2,特点
–接口中都是抽象方法
–通过interface关键字创建接口
–通过implements让子类来实现
–可以理解成,接口是一个特殊的抽象类
–接口突破了java的单继承的局限性
–接口和类之间可以多实现,接口和接口之间可以多继承
–接口是对外暴露的规则,是一套开发规范
–接口提高了程序的功能扩展,降低了耦合性

3,入门案例:

//测试 接口
		public class Test1_Inter {
			public static void main(String[] args) {
				//6,接口和抽象类一样,都不可以被实例化
		//		new Demo();
				Demo d = new DemoImpl();
				//7,多态对象为了统一调用标准,以父类为准
				d.save();
				d.delete();
			}
		}
		//1,通过interface关键字,定义接口
		interface Demo{
			//2,接口里全都是抽象方法(jdk1.8后可以是default/static的普通方法)
			abstract public void save() ;
			abstract public void delete() ;
		}
		//3,实现类想要使用接口的功能,需要和接口发生实现关系(类似继承)
		//5,实现类实现了接口,可以重写 所有 抽象方法
		class DemoImpl  implements  Demo{
		//	abstract public void save() ;
			@Override//注解
			public void save() {
				System.out.println("数据保存成功!");
			}
		//	abstract public void delete() ;
			@Override//注解
			public void delete() {
				System.out.println("数据删除成功!");
			}
		}
		//4,实现类实现了接口,可以是一个抽象的实现类
		//abstract class DemoImpl  implements  Demo{}
2、接口的用法

–1,构造方法
–2,成员变量
–3,成员方法

//测试 接口的使用
		//总结
		//1,接口里的构造方法--没有!!
		//2,接口里的变量--没有!有静态的常量,为变量自动拼接public static final
		//3,接口里的方法--都是抽象方法(1.8前),也可以有static或者default的普通方法(1.8后)
		//4,实现类--重写所有 抽象方法,否则就是一个抽象的 实现类
		//问题--接口里没有构造方法,那么,实现类怎么new的?
		//答案--不是接口里的构造方法,因为接口根本没有构造方法,其实找的是Object的构造方法
		public class Test2_Inter {
			public static void main(String[] args) {
				//3,使用接口里的静态常量?
		//		Inter.age = 30 ;//是final的常量
				System.out.println( Inter.age );//是static的资源
				System.out.println( new InterImpl().age );
				//8,测试
				Inter in = new InterImpl();
				in.show();
				in.save();
				Inter.test();//通过类名直接访问接口里的普通的静态方法
			} 
		}
		interface Inter{
			//1,接口里有没有构造方法?--没有--实现类到底怎么new的?--
		//	public Inter() {
		//		System.out.println(123);
		//	}
			//2,接口里有没有变量?--没有!!是static的final的常量public的
		//	public static final int age = 20 ;//接口会为你的变量,自动拼接public static final 
			int age = 20 ;//简写形式
			//4,接口里有没有普通方法?--有,只不过是jdk1.8才提供的,必须修饰成default/static
			default public void show() {
				System.out.println("这是jdk1.8的新特性");
			}
			static public void test() {
				System.out.println("这是jdk1.8的新特性");
			}
			//5,接口里有没有抽象方法?--有
			abstract public void save() ;
		//abstract public void save() ;//接口会为你的抽象方法,自动拼接public abstract
			void save() ;//简写形式
		}
		//6,实现类实现接口后,对于普通方法必须重写吗?--不是,要改才重写
		//7,实现类实现接口后,对于抽象方法必须重写吗?--是,否则就是一个抽象的实现类
		class InterImpl extends Object implements Inter{
			public InterImpl() {
				//不是接口里的构造方法,因为接口根本没有构造方法,其实找的是Object的构造方法
				super();
			}
			
			@Override
			public void save() {
				System.out.println("数据保存成功!");
			}
		}

3、接口的复杂用法
import java.io.Reader;
		//测试 接口的复杂用法
		//总结
		//1,继承关系extends: 子类和父类 / 接口和接口
		//2,实现关系implements: 实现类 和 接口
		//3,定义类: class   /  abstract class 
		//4,定义接口: interface
		//5,子类继承了父类后,如果有抽象方法,需要重写,否则就是一个抽象的子类
		//6,实现类 实现了 接口后,需要重写接口里的 所有抽象方法,否则就是一个抽象的实现类
		public class Test3_Inter {
			public static void main(String[] args) {
		//2,左侧写的接口到底是谁?--要看你想用哪个接口的功能,左侧就写谁
				Inter2 in = new Inter2Impl() ;
				in.save();
				int rows = in.update(2) ;
				System.out.println(rows);
				
				System.out.println( in.update(2) );
				in.delete("jack");
			}
		}
		interface Inter1{
			void save();
			int update(int id);
		}
		interface Inter3{
			void delete(String name);
		}
		//1,接口间是继承关系,而且可以多继承
		interface Inter2 extends Inter1 , Inter3{
			
		}
		//4,实现类和接口,是实现关系,还可以多实现
		class Inter3Impl implements Inter3 , Inter1 {
			public void delete(String name) {
				System.out.println("删除成功!");
			}
			public void save() {
				System.out.println("保存成功!");
			}
			public int update(int id) {
				System.out.println("更新成功!");
				return 5;
			}
		}
		//5,实现类可以在单根继承的同时,多实现
		//Inter4Impl需要重写Inter1和Inter3里的 所有抽象方法,否则就是一个抽象类
		abstract class Inter4Impl extends Object implements Inter1 , Inter3{
		//Inter4Impl需要重写Inter1和Inter3和抽象类Reader里的 所有抽象方法,否则就是一个抽象类
		//abstract class Inter4Impl extends Reader implements Inter1 , Inter3{
			
		}

		//3,实现类,实现了接口.需要把接口里 所有抽象方法都重写.
		//Inter2接口里的3个方法都要重写
		class Inter2Impl implements Inter2{
			@Override
			public void delete(String name) {
				System.out.println("删除记录成功!"+name);
			}
			@Override
			public void save() {
				System.out.println("数据保存成功!");
			}
			@Override
			public int update(int id) {
				System.out.println("数据已经更新");
				return 5;
			}
		}

六、总结

1、类和类的关系:继承 extends / 单继承 / 单根继承
-- 继承的意义:为了提高代码的复用性,减少了代码的编写提高开发效率。

-- 方法重写的意义:在不修改父类源码的前提下,在子类中重写业务,从此使用的就是重写后的功能。

   -- 要求子类的方法声明和父类一样,只要改方法体。

-- 有了继承有了重写就产生了多态,多态的意义:为了统一程序的调用标准,标准就是父类。

-- 多态 也就是向上转型/向上造型。

-- 向下造型的意义:很少用,相当于想要使用子类的特殊功能,还不如直接创建子类对象简单。

-- class A extends B

-- 其中,A和B都是类,A是子类,B是父类,A就拥有了B的所有功能(除了私有的和构造方法)




-- 其他知识点:this 和super  ,构造方法,各种代码块...
2、类和接口关系:实现implements / 单实现 / 多实现
-- class A implements B,C

-- 其中,A是实现类,B和C是接口

-- 要求A 可以把 B 和C 接口里的所有 抽象方法 都重写掉,否则 A 就是抽象类

-- 接口不能创建对象

-- 接口里没有构造方法,接口里都是常量,接口里都是抽象方法
3、接口和接口关系:继承extends / 单继承 / 多继承
-- 接口的多继承的关系,打破了java单继承的局限性

-- interface A  extends  B,C

-- 其中,A B C 都是接口,A是子接口,同时拥有B和C接口里的所有功能

-- class AImpl implements  A

-- 要求AImpl需要重写A接口里的所有方法(是包含B和C接口的所有方法),否则就是抽象类
4、接口和抽象类的区别!!!
-- 相同点:都是抽象层,都不能实例化                      

-- 不同点:

   -- 1、抽象类用abstract关键字描述,接口用interface

   -- 2、子类和抽象类之间是extends关系,实现类和接口之间是implements关系

   -- 3、抽象类中 可以  有构造方法 ,接口里 不能 出现 构造方法

   -- 4、抽象类里可以有 变量,接口里没有变量全都是静态的常量

   -- 5、接口里定义常量的语法:public static final String NAME="jack",会为变量自动拼接public static final

   -- 6、抽象类里 可以有普通方法  也可以有 抽象方法,接口都是抽象方法

   -- 7、抽象类和子类之间是继承关系,而且java中,只支持单继承

   -- 8、接口突破了java单继承的局限性,因为接口可以多继承也可以多实现,甚至可以继承的同时多实现

   -- 9、接口的复杂用法

       -- 多继承: interface A  extends  B,C  其中A是子接口,同时拥有自己的和BC的功能

       -- 多实现: class AImpl implements M,N,O,P 其中AImpl是实现类,需要同时重写MNOP的所有抽象方法,否则就是一个抽象类

.

2、类和接口关系:实现implements / 单实现 / 多实现
-- class A implements B,C

-- 其中,A是实现类,B和C是接口

-- 要求A 可以把 B 和C 接口里的所有 抽象方法 都重写掉,否则 A 就是抽象类

-- 接口不能创建对象

-- 接口里没有构造方法,接口里都是常量,接口里都是抽象方法
3、接口和接口关系:继承extends / 单继承 / 多继承
-- 接口的多继承的关系,打破了java单继承的局限性

-- interface A  extends  B,C

-- 其中,A B C 都是接口,A是子接口,同时拥有B和C接口里的所有功能

-- class AImpl implements  A

-- 要求AImpl需要重写A接口里的所有方法(是包含B和C接口的所有方法),否则就是抽象类
4、接口和抽象类的区别!!!
-- 相同点:都是抽象层,都不能实例化                      

-- 不同点:

   -- 1、抽象类用abstract关键字描述,接口用interface

   -- 2、子类和抽象类之间是extends关系,实现类和接口之间是implements关系

   -- 3、抽象类中 可以  有构造方法 ,接口里 不能 出现 构造方法

   -- 4、抽象类里可以有 变量,接口里没有变量全都是静态的常量

   -- 5、接口里定义常量的语法:public static final String NAME="jack",会为变量自动拼接public static final

   -- 6、抽象类里 可以有普通方法  也可以有 抽象方法,接口都是抽象方法

   -- 7、抽象类和子类之间是继承关系,而且java中,只支持单继承

   -- 8、接口突破了java单继承的局限性,因为接口可以多继承也可以多实现,甚至可以继承的同时多实现

   -- 9、接口的复杂用法

       -- 多继承: interface A  extends  B,C  其中A是子接口,同时拥有自己的和BC的功能

       -- 多实现: class AImpl implements M,N,O,P 其中AImpl是实现类,需要同时重写MNOP的所有抽象方法,否则就是一个抽象类

       -- 继承的同时多实现: class AImpl extends Object implements M,N 一定是先继承后实现
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值