继承

继承

一,继承的概述:

●多个类中哦个存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为只要继承单独的那个类即可。

●多个类可以称为子类,单独这个类称为父类或者超类。

●子类可以直接访问父类中的非私有的属性和行为。

●通过extends关键字让类与类之间产生继承关系。

×class SubDemo extends Demo{}

●继承的出现提高了代码的复用性。

●继承的出现让类与类之间产生了关系,提供了多态的前提。

二,继承的特点:

●Java只支持单继承,不支持多继承。

×一个类之可以有一个父类,不可以有多个父类。

●Java支持多层继承(继承体系)

●定义继承需要注意:

×不要仅为了获取其他类中某个功能而去继承

×类与类之间要有所属("is a")关系,xx1是xx2的一种。

/*
子父类出现后,类成员的特点;


类中成员:
1,变量。
2,函数。
3,构造函数。


1,变量
如果子类中出现非私有的同名成员变量时,
子类要访问本类的变量,用this
子类要访问父类中的同名变量,用super。


super的使用和this的使用几乎一致。
this代表的是本类对象的引用。
super代表的是父类对象的引用。
*/
class Fu
{
int  num = 4 ;
}
class Zi extends Fu
{
int num = 5 ;
void show ()
{
System.out.print(super.num);
}
}
class ExtendsDemo
{
public static void main(String [] args)
{
Zi z = new Zi ( ) ;
z.show( ) ;
System.out.print("~~~~");
System.out.println(z.num);
}
}

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


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


注意:千万不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。所属关系 is a  。
*/
/*
java语言中:java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同是,子类对象不确定要运行哪一个。
但是java保留这种机制,并用另一种体现形式来完成表示。叫多实现。


java支持多层继承。也就是一个继承体系,


如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系中父类的描述,因为父类中定义的是该类体系中的共性内容。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经可以基本使用了。


那么具体调用时,要创建最子类的对象,为什么呢?
一是因为有可能父类不能创建对象。
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。


简单一句话:查阅父类功能,创建子类对象使用功能。


聚集:has a 


聚合:


组合:
*/


class Person
{
String name;
int age;
}


class Student extends Person
{
void study( )
{
System.out.println("good study");
}


}


class Worker extends Person
{
void work( )
{
System.out.println("good work");
}
}




class  JiCheng
{
public static void main(String[] args) 
{
System.out.println("Hello World!");
}
}

三,super关键字

●super和this的用法相同

●this代表本类应用

●super代表父类应用

●当子类出现同名成员时,可以用super进行区分

●子类要调用父类构造函数时,可以使用super语句。

四,函数覆盖(override)

●子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。

●父类中的私有方法不可以被覆盖。

●在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。

●覆盖注意事项:

×覆盖时,子类方法权限一定要大于 等于父类方法权限

×静态只能覆盖静态

●覆盖的应用:

×当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

五,子类的实例化过程

●子类中所有的构造函数默认都会访问父类中空参数的构造函数

●因为每一个构造函数的第一行都有一条默认的语句super();

●子类会具备父类中的参数,所以要先明确父类是如何对这些数据初始化的。

●当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。

六,final关键字

●final可以修饰类,方法,变量。

●final修饰的类不可以被继承。

●final修饰的方法不可以被覆盖。

●final修饰的变量是一个常量。只能被赋值一次。

●内部类只能访问被final修饰的局部变量。

七,抽象类

1,抽象类概述

●抽象类定义:

×抽象就是从多个事物中将共性的,本质的内容抽取出来。

×例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。

●抽象类:

×Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类

●抽象方法的由来:

×多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。

×例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫细节。

2,抽象类的特点

●抽象类和抽象方法必须用abstract关键字来修饰。

●抽象方法只有方法声明,没有方法体,定义在抽象类中。

×格式:修饰符abstract 返回值类型 函数名(参数列表);

●抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:

×抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在 的是狼和狗。

×而且抽象类即使创建了对象,调用抽象方法也没有意义。

●抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类

3,抽象类举例代码

/*
当多个类中出现相同功能,但是功能主体不同,
这是可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体。


抽象:看不懂。


抽象类的特点:
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类都必须被abstract关键字修饰。
3,抽象类不可以用new创建对象。因为调用抽象方法没意义。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。




抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。


抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。




特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。




练习:


abstract 关键字,和哪些关键字不能共存。
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。
而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。
可是抽象方法运行没意义。






抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化。


*/


abstract class Student
{
abstract final void study();
//abstract void study1();
void sleep()
{
System.out.println("躺着");
}
}
/*


class ChongCiStudent extends Student
{
void study()
{
System.out.println("chongci study");
}
}


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


class AdvStudent extends Student
{
void study()
{
System.out.println("adv study");
}
}
*/
class AbstractDemo 
{
public static void main(String[] args) 
{
//new Student();
//new BaseStudent().study();
}
}


/*
假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性:
姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个
奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方
法进行属性访问。


员工类:name id pay


经理类:继承了员工,并有自己特有的bonus。




*/


class Employee
{
private String name;
private String id;
private double pay;


Employee(String name,String id,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
}

public abstract void work();


}






class Manager extends Employee
{
private int bonus;
Manager(String name,String id,double pay,int bonus)
{
super(name,id,pay);
this.bonus = bonus;
}
public void work()
{System.out.println("manager work");
}
}


class Pro extends Employee
{
Pro(String name,String id,double pay)
{
super(name,id,pay);
}
public void work()
{
System.out.println("pro work");
}
}








class  
{
public static void main(String[] args) 
{
System.out.println("Hello World!");
}
}


八,接口

●格式:

interface {}

●接口中的成员修饰符是固定的。

×成员常量:public static final

×成员函数:public abstract

●接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。

1,接口的特点

●接口是对外暴露的规则。

●接口是程序的功能扩展。

●接口可以用来多实现。

●类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。

●接口与接口之间可以有几次关系。

interface Inter
{
public static final double PI = 3.14 ;
public abstract void show ( ) ;
}
class Test implements Inter
{
public void show ( )
{
int x=0 ;
while ( x<10)
{
x++;

System.out.print(x+",");
}

}
}
class  InterfaceDemo
{
public static void main(String[] args) 
{
Test t = new Test ( ) ;
System.out.println( t.PI);
System.out.println( Test.PI);
System.out.println( Inter.PI);
t.show ( );
}
}

九,多态

定义:某一类事物的多种存在型态。

●体现:

父类或者接口的引用指向或者接收自己的子类对象。

●作用:

多态的存在提高了程序的扩展性和后期可维护性

●前提:

×需要存在继承或者实现关系

×要有覆盖操作

多态的特点:

●成员函数:

×编译时:要查看引用变量所属的类中是否有所调用的成员。

×在运行时:要查看对象所属的类中是否有所调用的成员。

●成员变量:

×只看引用变量所属的类。

/*
需求:数据库的操作。
数据是:用户信息。
1,连接数据库。JDBC     Hibernate
2,操作数据库。
crud   c  create   创建  r  read 读取   u    update 修改     d    delete删除
3,关闭数据库连接。
*/
interface UserInfoDao
{
public void add(User user);
public void delete(User user);
}


class UserInforByJDBC implements UserInfoDao
{
public void add (User  user)
{
1, 连接数据库。;
2,使用sql添加语句添加数据。;
3,关闭连接。;
}
public void delete (User  user)
{
1, 连接数据库。;
2,使用sql添加语句添加数据。;
3,关闭连接。;
}
}




class  DBOperate
{
public static void main(String[] args) 
{
UserInfoDao ui = new UserInforByJDBC();
ui.add(user);
ui.delete(user);
}
}


/*
需求:
电脑运行实例
电脑运行基于主板。
*/
interface PCI
{
public void open ( ) ;
public void close ( ) ;
}
class MainBoard 
{
public void run ( )
{
System.out.println("mainboard run");
}
public void usePCI (PCI p)
{
if ( p!=null)
{
p.open ( ) ;
p.close ( ) ;
}
}
}
class NetCard implements PCI 
{
public void open ( )
{
System.out.println("netcard open") ;
}
public void close ( )
{
System.out.println ("netcard close") ;
}
}




class DuoTaiDemo2 
{
public static void main(String[] args) 
{
MainBoard mb = new MainBoard ( ) ;
mb.run ( ) ;
mb.usePCI (new NetCard ( ) ) ;
}
}

内部类

●将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

●访问特点:

×内部类可以直接访问外部类中的成员,包括私有成员。

×而外部类要访问内部类中的成员必须要建立内部类的对象。

内部类的位置

●内部类定义在成员位置上

×可以被private static成员修饰符修饰。

×被static修饰的内部类只能访问外部类中的静态成员。

●内部类定义在局部位置上

×也可以直接访问外部类中的成员。

×同时可以访问所在局部中的局部变量,但必须是被final修饰的。

/*
内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有一个外部类的引用,格式  外部类名.this
2,外部类要访问内部类,必须建立内部类对象。


访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式:
外部类名.内部类名  变量名 = 外部类对象.内部类对象;
Outer.Inter in = new Outer().new Inter();
2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。


在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inter().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inter.function();


注意:当内部类中定义了静态成员,该内部类必须是static的。
 当外部类中的静态方法访问内部类时,内部类也必须是static的。


当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事物在使用外部事物的内容。
*/
class Outer
{
private int x = 3;
class Inter
{
int x = 5;
void function()
{
int x =8;
System.out.println("Inter="+Outer.this.x);
}
}
void method()
{
Inter in = new Inter();
in.function();
}
}
class InterClassDemo 
{
public static void main(String[] args) 
{
Outer out = new Outer();
out.method();
//直接访问内部类中的成员。
//Outer.Inter in = new Outer().new Inter();
//in.function();
}
}

匿名内部类

●就是内部类的简化写法。

●前提:

×内部类可以继承或实现一个外部类或者接口。

●格式为:

×new外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容)}

●简单理解:

×就是建立一个带内容的外部类或者接口的子类匿名对象。

/*
匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口.
3,匿名内部类的格式:new父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。
5,匿名内部类中定义的方法最好不要超过三个
*/
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
int x = 3;
/*
class Inner extends AbsDemo
{
void show()
{
System.out.println("show:"+x);
}
}
*/


public void function()
{
//new Inner().show();


new AbsDemo()
{
void show()
{
System.out.println("x="+x);
}
}.show();
}
}


class InnerClassDemo2 
{
public static void main(String[] args) 
{
new Outer().function();
}
}

异常

●异常的体系

×Throwable

㈠Error

①通常出现重大问题如:运行的类不存在或者内存溢出等。

②不编写针对代码对其处理

㈡Excepyion

①在运行时运行出现的一些情况,可以通过try catch finally

●Exception和Error的子类名都是以父类名作为后缀。

Throwable中的方法

●getMessage()

×获取异常信息,返回字符串。

●toString()

×获取异常类名和异常信息,返回字符串。

●printStackTrace()

×获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

●printStackTrace(PrintStream s )

×通常用该方法将异常内容保存在日志文件中,以便查阅。

throws和throw

●/*
因为项目中会出现特有的问题。
而这些问题并未被java多描述并封装对象。
所以对于这些特有的问题可以被按照java对问题封装的思想。
将特有的问题,进行自定义的异常封装。


自定义异常。


需求:在本程序中,对于除数是负数,也视为是错误的是无法进行运算的。
那么就需要对这个问题进行自定义的描述。


当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
那么在内部try catch处理。
要么在函数上声明让调用者处理。


一般情况下,在函数内出现异常,函数上需要声明。


发现打印结果中只有异常的名称,却没有异常的信息。
因为自定义的异常并未定义信息。


如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息传递给父类通过super语句
那么就可以直接通过getMessage方法获取自定义的异常。


自定义异常:
必须是自定义类继承Exception。


继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具有可抛性,这个可抛性是Throwable这个体系中独有特点。


只有这个体系中的类和对象才可以被throws和throw操作。


throws和throw的区别
throws使用在函数上。
throw使用在函数内。


throws后面跟的异常类。可以跟多个。用逗号隔开。
throw后跟的是异常对象。
*/
class FuShuException extends Exception//getMessage();
{
private int value;
FuShuException(String msg,int value)
{
super(msg);
this.value = value;
}
public int getvalue()
{
return value;
}
}
class Demo
{
int div(int a,int b)throws FuShuException
{
if(b<0)
throw new FuShuException("出现了除数是负数的情况/by fushu", b);//手动通过throw关键字抛出一个自定义异常对象。
return a/b;
}
}


class ExceptionDemo3 
{
public static void main(String[] args) 
{
Demo d = new Demo();
try
{

int x = d.div(4,-1);
System.out.println("x="+x);
}
catch (FuShuException e)
{
System.out.println(e.toString());
//System.out.println("除数出现负数啦!!");
System.out.println("错误的负数是:"+e.getvalue());
}

System.out.println("over");
}
}

异常处理

/*
异常的处理
java提供了特有的语句进行处理。
try
{
需要被检测的代码;
}
catch(异常类  变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}


3,对捕获到的异常对象进行常见方法操作。
String getMessage();获取异常信息。


在函数上声明异常。
便于提高安全性,让调用者进行处理。不处理编译失败。


对多异常的处理。
1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。


建议在进行catch处理是,catch中一定要地定义具体处理方式。
不要简单定义一句e.printStackTrace(),
也不要简单的就书写一条输出语句。
*/


class Demo
{
int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException  //在功能上通过throws的关键字声明了该功能有可能会出现问题。
{
int[] arr = new int[a];
System.out.println(arr[4]);
return a/b;
}
}


class ExceptionDemo 
{
public static void main(String[] args)//throws Exception 
{
Demo d= new Demo();
try
{
int x = d.div(4,0);
System.out.println("x="+x);
}
/*
catch (Exception e)
{
//System.out.println("除零啦!!");
//System.out.println(e.getMessage());//  /by zero
System.out.println(e.toString());//异常名称:异常信息。
//e.printStackTrace();//异常名称,异常信息,异常出现的位置。
//其实jvm默认的异常处理机制,就是在调用printStackTrace方法。
//打印异常的堆栈的跟踪信息。
}
*/
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e.toString());
System.out.println("角标越界啦!!");
}

System.out.println("over");
}
}


自定义异常

/*
Exception中有一个特殊的子类异常ArithmeticException运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。


之所以不愿在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,
对代码进行修正。


自定义异常时:如果该异常的发生,无法在继续进行运算,
就让自定义异常继承RuntimeException。


对于异常分两种:
1,编译时被检测的异常。
2,被编译时不被检测的异常(运行时异常。RentimeException以及其子类)
*/
class Demo
{
int div(int a,int b)//throws ArithmeticException
{
if(b==0)
throw new ArithmeticException("被零除啦");
return a/b;
}
}
class ExceptionDemo4  
{
public static void main(String[] args) 
{
Demo d = new Demo();
int x = d.div(4,0);
System.out.println("x="+x);
System.out.println("over");
}
}


异常细节

●RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。

●一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。

●如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。

●介绍异常在分层设计时的层内封装。

●例如:class LanPingException extends Exception
{
LanPingException(String message)
{
super(message);
}
}


class MaoYanException extends Exception
{
MaoYanException(String message)
{
super(message);
}
}




class NoPlanException extends Exception
{
NoPlanException(String msg)
{
super(msg);
}
}


class Computer
{
private int state = 3;
public void run()throws LanPingException,MaoYanException
{
if(state==2)
throw new LanPingException("蓝屏了");
if(state==3)
throw new MaoYanException("冒烟了");


System.out.println("电脑运行");
}
public void reset()
{
state = 1;
System.out.println("电脑重启");

}
}


class Teacher
{
private String name;
private Computer cmpt;


Teacher(String name)
{
this.name = name;
cmpt = new Computer();


}


public void prelect()throws NoPlanException
{
try
{
cmpt.run();
}
catch (LanPingException e)
{
cmpt.reset();
}
catch (MaoYanException e)
{

test();
throw new NoPlanException("课时无法继续"+e.getMessage());

}
System.out.println("讲课");
}
public void test()
{
System.out.println("练习");
}


}






class ExceptionTest 
{
public static void main(String[] args) 
{
Teacher t = new Teacher("毕老师");
try
{
t.prelect();
}
catch (NoPlanException e)
{
System.out.println(e.toString());
System.out.println("换老师或者放假");
}

}
}

包(package)

●对类文件进行分类管理。

●给类提供多层命名空间。

●写在程序文件的第一行。

●类名的全称是 包名.类名。

●包也是一种封装形式。

包之间的访问

●被访问的包中的类权限必须是public的。

●类中的成员权限:public或者protected

●protected是为其他包中的子类提供的一种权限

import

●简化类名。

●一个程序文件中只有一个package,可以有多个import。

●用来导包中的类,不导入包中的包。

●通常写import mypack.Demo;

而不写import mypack.*;

jar包

●Java的压缩包

×方便项目的携带。

×方便于使用,只要在classpath设置jar路径即可。

●数据库驱动,SSH框架等都是以jar包体现的。

jar包的操作

通过jar.exe工具对jar的操作。

×创建jar包

jar -tvf mypack.jar packa packb

×查看jar包

jar -tvf mypack.jar [>定向文件]

×解压缩

jar -xvf mypack.jar

×自定义jar包的清单文件

jar -cvfm mypack.jar mf.txt packa packb

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值