java之7天 继承,final,接口,抽象类

1 篇文章 0 订阅
1 篇文章 0 订阅

继承

/**
将学生和工人的共性描述提取出来,单独进行描述, 只要让学生和工人与单独描述的这个类有关系,就可以了.

继承:
1.提高代码的复用性
2.让类与类之间产生了关系, 有了这个关系类,才有了多态的特性..
*/

class Persion{

  String name;
  int age;
}

class Student extends  Person{
  //String name;
  //  int age;
void  study(

  System.out.println("goog study");
)

class Worker extends Person{
  //  String name;
//  int age;
  void work(){
   System.out.println("good work");
  }
}

}
/*
注意:千万不要为了获取其他类的功能,简化代码而继承, 必须是类与类之间有所属关系才可以继承,所属关系  is a.
*/

class A{
  void demo1(){}
  void demo2(){}
}

class B extends A
{
   //void demo1(){}  发现 B也有 demo2() 这个功能 说明不能乱继承,我们可以将 demo抽成出一个 父类 .但是 B 不能继承 A
   void demo3()}
}

/*
Java语言中,Java只支持单继承,不支持多继承.
因为多继承 容易带来安全隐患.
当功能内容不同时,子类对象不确定要运行那个
但是java保留了这种机制,并用另一种体现形式来完成,多实现
*/
class A{

 void show(){ 
   System.out.println("A");
  }
}

class B{

 void show(){ 
   System.out.println("B");
  }
}

class C extends A,B{

 public statiac void main(String [] args){

    C  c=new C();
    c.show();  //如果出现多继承  此时就不知道是打印 A 还是 B 所以java不支持多继承. 
 }
}


/*
要先使用体系,先查阅体系父类的描述,因为父类中定义了该体系中共性功能.
通过了解共性功能,就可以知道该体系的基本功能

在具体调用时,要创建最子类的对象,为什么呢?
1:一是因为有可能父类不能创建独享
2.创建子类对象可以使更多的个功能,包括基本的也包括特有的
*/


//聚集 : has a 分为下面两种

1.聚合: 球队和 球员    (球队少一个球员没有什么大的问题)
2.组合: 手是人体一部分 (实物联系更紧密)


//子类 父类中的成员的特点
类中的成员
1.变量
2.函数
3.构造函数


//不同的变量

class Fu{
  int num1=4;

}

class Zi extends Fu{
  int num2=5;
}


class  ExtendsDemo{

  Zi z=new Zi();
  System.out.println(z.num1+"...."+z.num2);  //  4....5
}



//相同的变量

class Fu{
  int num1=4;

}

class Zi extends Fu{
  int num1=5;
}


class  ExtendsDemo{

  Zi z=new Zi();
  System.out.println(z.num1+"...."+z.num1);  //  5....5
}


//子类中的方法

class Fu{
 /*private*/  int num1=4;

}

class Zi extends Fu{
  int num1=5;

  void show(){
     System.out.println(this.num1);   //this 表示本类对象的引用   输出  5
     System.out.println(super.num1):  //super表示父类对象的引用  输出  4,如果num为private 不能使用 num
  }
}


class  ExtendsDemo{

  Zi z=new Zi();
  z.show();

//  5  4
}







//如果 子类中没有 和父类相同的变量 那就 this=suuper 中的变量

class Fu{
  int num=4;  
}
class Zi extends Fu{
	//int num=5;
	void show(){
		
		System.out.println(this.num);
		System.out.println(super.num); //
		
	}
	
}

public class day7_T1 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Zi z=new Zi();
  
			z.show();
               //   4  4 
	}

}


//父子类中 函数的特点

class Fu{
 void show1(){
   System.out.println("fu show");	 
 }
}
class Zi extends Fu{
	
	void show2(){
		System.out.println("zi show");
		
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Zi z=new Zi();
			z.show1();
			z.show2();
	}
//输出  
fu show
zi show
}



//父子类 函数名相同


/*
当子类和父类出现一模一样的函数时
当子类对象调用该函数的时候,会运行子类函数的内容
如同父类的函数被覆盖一样

这种情况是函数的另一种特性  : 重写(覆盖,可以发现 重写 发生在子类和父类之间 ,函数每个部分完全相同)

当子类继承父类的时候,子类就会沿袭父类的所有公共成员.
*/
class Fu{
 void show(){
   System.out.println("fu show");	 
 }
}
class Zi extends Fu{
	
	void show(){
		System.out.println("zi show");
		
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Zi z=new Zi();
			z.show();
	}
       //zi show
}



//重写的特性2

//可以看出 适合后期程序的升级 和 扩展

// 重写可以保留父类的功能定义,并可以重写功能的内容.

class Fu{
 void show(){
   System.out.println("fu show");	 
 }
}
class Zi extends Fu{
	
	void show(){
		System.out.println("zi show");
		super.show();  //还可以继续使用父类的函数 或其他成员
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Zi z=new Zi();
			z.show();
	}
}


//注意事项

//重写 (覆盖)

1. 子类覆盖父类,必须保证子类权限大于等于 父类权限 ,才可以覆盖,否则编译失败
2. 静态只能覆盖静态.

重写: 父子类方法要一模一样  包括返回值
重载: 只看同名函数的参数列表


//注意下面不是重写 

class Fu{
 private void show(){
   System.out.println("fu show");	 
 }
}
class Zi extends Fu{
	
	void show(){  //这里没有重写  ,因为 子类根本就不知道父类有 show 这个防范
		System.out.println("zi show");
		//super.show();  //还可以继续使用父类的函数 或其他成员
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Zi z=new Zi();
			z.show();
	}
}



//父子类中的构造函数特点

//父子类中 构造函数 不是重写 因为  方法名不同

class Fu{
  Fu(){
	  System.out.println("fu run");
  }
}
class Zi extends Fu{
	
	Zi(){
//super();  默认 在第一行 有这个 语句 调用父类 .
		System.out.println("zi run");
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
			Zi z=new Zi();
	}
}
//输出 
fu run
zi run 

//说明 在初始化子类的时候 先加载父类 然后加载子类    

继续证明上面的观点--接下来看看 
class Fu{
	static{  //静态代码块    只要该类被JVM 加载到内存 就会运行这个 里面的内容 
		System.out.println("fu static run");
	}
	
	{  //构造代码块  在所有 构造函数前都会运行 ,除非不用构造函数 
		System.out.println("fu gouzao run");
	}
	
  Fu(){
	  System.out.println("fu run");
  }
}
class Zi extends Fu{
	static{
		System.out.println("zi static run");
		
	}
	
	{
		System.out.println("zi gouzao run");
	}
	
	Zi(){
		//super(); 默认都有  这行
		System.out.println("zi run");
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
			Zi z=new Zi();
		
	}
}

//输出
fu static run
zi static run
fu gouzao run
fu run
zi gouzao run
zi run



//子类中所有的构造方法的第一行都会默认有 super() 这行 可以显示 调用 和 可以省略
(因为初始化的过程必须先做.只有做了,子类才能使用父类成员)


class Fu{
	static{  //静态代码块    只要该类被JVM 加载到内存 就会运行这个 里面的内容 
		System.out.println("fu static run");
	}
	{  //构造代码块  在所有 构造函数前都会运行 ,除非不用构造函数 
		System.out.println("fu gouzao run");
	}
  Fu(){
	  System.out.println("fu run");
  }
  Fu(int x){  //如果不调用该类中的这个构造方法 就不会被运行
	  System.out.println("fu run"+x);
  }
}
class Zi extends Fu{
	static{
		System.out.println("zi static run");
		
	}
	{
		System.out.println("zi gouzao run");
	}
	Zi(){
		//super(); 默认都有  这行
		System.out.println("zi run");
	}
	Zi(int x){
		//super(); 默认都有  这行
		System.out.println("zi run"+x);
	}
	
}
public class day7_T1 {
	public static void main(String[] args) {
			Zi z=new Zi(4);
		
	}
}
//输出 
fu static run
zi static run
fu gouzao run
fu run
zi gouzao run
zi run4





//为什么子类一定要访问父类中的构造函数??


class Person{
	String name;  //默认为0  
	
	 //Perseon(){} 显示写出 默认构造函数 
	
	Person(String name){  //发现 我们没有写 那个默认的构造函数 
		this.name=name;
		System.out.println("fu run"+this.name);
	}
}

class Student extends Person{
	
	Student(){
		//super();   报错  因为 父类中 没有显示写出构造函数,而出现了其他构造函数,一般我们建议将 类的默认构造函数显示写出来.
		super("xx");  //如果没有写父类默认构造函数 ,只能调用 其他构造函数
		System.out.println("zi run");
		//super("xx"); 写这里也报错 super 必须放在第一行 .
	}
	
	Student(String name){
		//super(); 这里也不能写 
		super(name);
		System.out.println("zi run" +this.name); //如果不调用父类的构造函数 我们就拿不到这个值了.
	}
	
}

public class day7_T2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student stu=new Student();
               System.out.println(new Person("xx").name);
	}

}

//输出
fu runxx
zi run
fu runxx
xx

只要子类继承了父类,就可以沿袭父类中所有公共成员, 既然 需要使用到 父类的成员 ,所以父类 必须要先实例化.必须先加载 ,所以 super只能放在第一行 ,这样就是为了后面的子类能使用其父类中的成员.

上面由于只写了一个有参数构造函数 ,所以下面 的Student 只能都调用 那个有参数的构造函数.


//this 和super 的关系  (一样的用法)

class Person  /*extends Object*/{
	String name;  //默认为0  
	
	 //Perseon(){} 显示写出 默认构造函数 
	
	Person(String name){  //发现 我们没有写 那个默认的构造函数 
		this.name=name;
		System.out.println("fu run"+this.name);
	}
}

class Student extends Person{
	
	Student(){
		super("xx");  //如果没有写父类默认构造函数 ,只能调用 其他构造函数
		System.out.println("zi run");
	}
	
	Student(String name){
		this();  //调用子类自己的  默认构造函数 由于 上面的构造函数 中调用 super("xx") 所以这句话可以了
		//super();  // 发现 写了this()后 这句报错了, 因为  super 要在第一行 
		//this();  //发现 先写 super后 在写 this() 也不行    因为  构造函数中 只能调用一次 父类构造方法 ,而且 super要放在第一行 ,所以这两个不能同时出现
		System.out.println("zi run" +this.name); //如果不调用父类的构造函数 我们就拿不到这个值了.
	}
	
}

public class day7_T2 {
	public static void main(String[] args) {
		Student stu=new Student("aa");
	}

}

//发现  this() 和 super() 不能同时出现在子类的构造函数中.
this() 可以代替super()  因为  this()中 也有 super() 这个语句



//final: 最终,作为一个修饰符
1.可以修饰类, 函数 ,变量
2.被final修饰的类不可以继承,(避免 ,子类继承父类后,将父类里面功能该个面目全非)
3.被final修饰的方法不可以重写 (如果某个类中一些方法 可以重写,有些不行)
4.被final修饰的变量 是一个常量 ,只能赋值一次, 即可以修饰成员变量,也可以修饰局部变量.(常量建议都全大写,多个单词间使用 "_" 下划线连接)

   当描述事物的时候一些数据的出现值是固定的,那么这是为了增强阅读性,都给这个值起个名字,方便阅读,而这个值不需要改变,所以就加上final

5.内部类定义在该类的局部位置上时,只能访问该具备被final修饰的局部变量

class /*final*/ ArraySort{
	
	final static int NUMBER=9; //终身为 5
	final double PI_VALUE=3.14;  //常量
	
	/*final*/ void intSort(int[] arr){  //修饰方法
                  final int INDEX=5;  //终身为 5
		System.out.println("int 类型的数组 开始排序....");
		//功能代码前面的例子有
	}
	
}

class  SubSort extends ArraySort{
	void intSort(int[] arr){  //如果 父类方法 被修饰后  这句就报错了
		System.out.println("haha");  //被子类 重新出来 haha 了   失去了原有数组排序功能. 此时就只有 使用 final了 防止 其他类来重新类中的方法.
	}
	
}


抽象类

/**
 * 当多个类中初相相同功能,但是功能主体不同,这时候可以进行向上抽取,只抽取功能定义,而不定义主体.
 * 
 * 抽象 :看不懂
 * 1.抽象方法一定在抽象类中
 * 2.抽象方法和抽象类都必须被abstract关键字修饰
 * 3.抽象类不可以用new 创建对象,因为调用抽象方法没有意思
 * 4.抽象类中的抽象方法要被使用,必须由子类复写所有的抽象方法,建立子类对象调用.
 *   如果子类只覆盖部分抽象方法,那么子类还是一个抽象类.
 * 
 * 抽象类和一般类没有太大的不同
 * 该如何描述事物,就如何描述事物,只不过,该事物出现一些不太明确的行为.juic
 * 这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定义主体.
 * 通过抽象方法来表示 
 * 
 * 抽象类比一般类多个抽象函数
 * 抽象类不可以实例化
 * 抽象类中可以不定义抽象方法
 * 
 * abstract 只能修饰 类和方法 不能修饰 变量
 * 还可以不让该类建立对象.
 */
abstract class Students{
	abstract void study();/*{
	System.out.println("study");  //如果子类 的行为不一样 这个方法就没有用了
}*/
}

class BaseStudent extends Students{
	
	void study(){
		System.out.println("base study");
	}
}

class AdvanceStudent extends Students{
	void study(){
		System.out.println("advance study");
	}
}


//案例2 采用抽象设计

/**
 * 假如我们在开发一个系统是需要对员工进行建模,
 * 员工包含3个属性, 姓名,工号,工资 
 * 经理也是员工,除了员工外还有奖金属性
 * 使用继承的思想设计出员工累和经理类,要求类中提供必要的方法进行属性访问.
 */
abstract class Employee{
	
	private String name;
	private String id;
	private double salary;  //工资
	
	public Employee(String name, String id, double salary) {
		this.name = name;
		this.id = id;
		this.salary = salary;
	}
	
	abstract void work();
}
class Professional extends Employee{ //专业人士
	public Professional(String name, String id, double salary) {
		super(name, id, salary);
	}

	@Override
	void work() {
		System.out.println("professional work");
	}
}

class Manager extends Employee{ //管理员
	private int bonus;  //奖金
	public Manager(String name, String id, double salary,int bonus) {
		super(name, id, salary);
		this.bonus=bonus;
		// TODO Auto-generated constructor stub
	}
	@Override
	void work() {
		System.out.println("manager work");
		
	}
	
}

//例子类


/**
 * [====模版方法设计模式===]
 * 1.在定义功能时候,功能的一部分是确定的,但是一部分是不确定,而确定的部分在使用不确定的部分,
 *  那么这时就将不确定的部分暴露出去,由该类的子类去完成.
 *  
 * 
 * 需求: 获取一段程序运行的时间
 * 原理: 获取程序开始和结束的时间差就可以了
 * 下面经过 三不变形 就成了 一个模版了
 */
abstract class GetRunTime{
	
	public final void getTime(){ //不想子类 把这个方法的功能给改了
		long start=System.currentTimeMillis();  //固定代码
		
		//封装这段代码的运行时间 ,如果代码段换了呢 
	/*	for (int i = 0; i < 1000; i++) { 
			System.out.println(i);     
		}*/
		runcode();                             //不固定代码  
		
		long end=System.currentTimeMillis(); //固定代码
		System.out.println("毫秒:"+(end-start));  //固定代码
		
	}
	public abstract void runcode();/*{
		for (int i = 0; i < 1000; i++) {
			System.out.println(i);   
		}
	}*/
	
	
}

class SubTime extends GetRunTime{
	@Override
	public void runcode() {
		for (int i = 0; i < 4000; i++) {  //变成 4000次
			System.out.println(i);
		}
	}
}


public class TemplateDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//GetRunTime grt=new GetRunTime();
		//grt.getTime();
		
		SubTime st=new SubTime();
		st.getTime();
	}

}


//接口

/**
 *接口:  初期的理解,可以认为是一个特殊的抽象类
 *   当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示
 *  
 * class: 用于定义类
 * interface:用于定义接口
 * 
 * 接口定义时,格式特点:
 * 1.接口中的常见定义,常量,抽象方法.
 * 2.接口中的成员都有固定修饰符
 *    常量:public static final 
 *    方法:public abstract  不能为 static的 
 *    
 * 接口: 是不可以创建对象, 因为有抽象方法 ,所以接口是一个特殊的抽象类
 * 需要被子类实现,子类对象接口中的抽象方法全部复写,子类才可以实例化,否则子类也是一个抽象类
 * 
 * 接口可以被类多实现.
 * java不提供 多继承  ,变成了多实现
 * 
 * 1.类      和      类的关系       继承 
 * 2.类      和     接口               实现 
 * 3.接口  和    接口                继承  
 *
 */
interface Inter{
	public static final int NUM=3;  //public static final 可省略
	public abstract void show();    //public abstract 可省略
}

interface InterA{
	public abstract void method();    //public abstract 可省略
	public abstract void show();   //没有方法主体,所以由子类自己定义主体
}

class Demo{
	public void function(){}  //
	
}

//继承一个父类 实现两个接口
class Test extends Demo implements Inter,InterA{

	@Override
	public void show() {  //股改了两类中的 show 方法
		System.out.println(this.NUM);
		//System.out.println(super.NUM);  //报错
	}

	@Override
	public void method() {
		System.out.println(Inter.NUM);
	}
}


public class InterfaceDemo {
	public static void main(String[] args) {
		Test test=new Test();
		System.out.println(Inter.NUM);  //3
		System.out.println(test.NUM);   //3 
		System.out.println(Test.NUM);   //3
		
		// test.NUM=4; //是常量所以值不能被覆盖
	}
}


//接口间关系



interface A{
	public abstract void show1();
	int show();
}
interface B extends A{  //  b 有两个方法了
	public abstract void show2();

	//boolean show(); 继承的接口中不能很出现这个情况   
}
interface C extends B{ //  c 有三个方法了
	public abstract void show3();
}

class InterRelation implements C{
	@Override
	public void show2() {}

	@Override
	public void show1() {}

	@Override
	public void show3() {}

	@Override
	public int show() {
		// TODO Auto-generated method stub
		return 0;
	}
}


//接口间的多继承


interface D{  //  因为  A E中没有 方法体 就不冲突
	public abstract void show4();
}
interface E { //  c 有三个方法了
	public abstract void show5();
}

interface F extends D,E{  //因为 D E中没有 方法体 就不冲突
	public abstract void show6();
}


//接口特点


/**
 * 接口的特点
 * 1.接口是对外暴露的规则
 * 2.接口是程序的功能扩展
 * 3.接口可以用来实现
 * 4.类和接口是实现的关系,而类可以继承一个类的同时实现多个接口
 * 5.接口和接口之间有多继承关系
 * 6.降低了耦合性.
 * 
 * 
 * 案例: 学生的行为
 *   
 * 继承 :  一般包含基本功能        is     (你是我 是 其中的一个)
 * 接口 : 一般用于定义扩展功能    like   (你像  我中的一个)
 */

abstract class StudentParent{
	//基本功能 定义在类中 
	abstract void study();
	void sleep(){
		System.out.println("sleep");
	}
	
	/*abstract void smoking(){//由于 又不是每个人都抽烟怎么办呢 ??
		System.out.println("我吸的XX牌子的烟");
	}*/
}
interface smoker{  //扩展功能 定义在接口中 
	void smking();
}

interface Wine{  //扩展功能 定义在接口 
    void drink();	
}

//学生 张三  除了学生外  还学会 抽烟喝酒
class ZhangSan extends StudentParent implements smoker,Wine{

	@Override
	void study() {}
	
	@Override
	public void smking() {}

	@Override
	public void drink() {}
}

  • 大小: 20.2 KB
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值