(6)Java面向对象之加强篇

时间:2021-12-05 17:23:46

Java面向对象之加强篇

面向对象三大特征之多态

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

例如:动物中的猫,狗;人中的男人,女人;

猫对应的类型是猫类型;  猫 x = new ();

同时猫也是动物中的一种,也可以把猫称为动物。

动物 y = new ()

动物是猫和狗具体事物中抽取出来的父类型;

父类型引用指向了子类对象。

体现:父类或者接口的引用指向或者接受自己的子类对象。

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

前提:需要存在继承或者实现关系

   需要覆盖操作;

多态特点:

成员函数:编译时:要查看引用变量所属的类是否有所调用的成员;

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

成员变量:只看引用变量所属的类。//面试考点

当静态方法或变量被覆盖一般面试题多,记住,父类走父类,子类走子类

多态的扩展性;

如代码:

abstract class Animal{
   abstract void eat();//定义一个抽象方法让其子类实现,这是多态前提
}
class Dog extends Animal{
public void eat(){
System.out.println(“啃骨头”);
  }
}
class Cat extends Animal{
public void eat(){
System.out.println(“吃鱼”);
public void play(){
System.out.println(“玩”);

  }
}
class DuoTaiDemo{
public static void main(String[] args){
  function(new Cat());
  function(new Dog());
}
public static void function(Animal a){//接收所有动物的公有的吃的行为
a.eat();
  }
}//大大的提高了程序的扩展性;但是只能使用父类中的成员;

多态转型:

示例:

Animal a = new Cat();//类型提升,向上转型

a.eat();

//如果想要阿姨猫的特有方法时,怎么操作?

//可以强制将父类的引用转成子类类型,向下转型

Cat c = (Cat)a;//向下转型。

c.play();

注意:多态自始至终都是子类对象在做着变化!

小细节:当我们传进去的不是需要的类型就会报错,所以还需要对传进去的类型坐判断

如:

main 主函数

function(new Cat());

public static void function(Animal a){

if(a intanceof Animal)//判断是否是动物类型

{sop(“haha”);}

If(a intanceof Cat)//判断是否是猫类型

{ Cat c = (Cat)a;//向下转型。

c.play();

}

}

关于多态的具体应用示例:

基础班学生:

学习,睡觉。

高级班学生:

学习,睡觉。

可以将这两类事物进行抽取

代码实例:

abstract class Student{
public abstract void study();
public void sleep(){
System.out.println("躺着睡");
}
}
class DoStudent{//定义类接收共性内容传入类类型对象
public void doSome(Student stu){
stu.study();
stu.sleep();
}
}
class BaseStudent extends Student{//基础班继承学生复写其方法
public void study(){
System.out.println("base study");
}
public void sleep(){
System.out.println("坐着睡");
}
}
class AdvStudent extends Student{
public void study(){
System.out.println(" adv study");
}
}
class DuoTaiDemo{
public static void main(String[] args) {
DoStudent ds = new DoStudent();
ds.doSome(new BaseStudent());//把子类对象作为参数传递给DoStudent
ds.doSome(new AdvStudent());//这样可以优化代码,这就是多态的应用方面体现
}
练习多态: 多态主板示例:

/*
需求:
电脑运行实例,
电脑运行基于主板。
*/
interface PCI{//定义接口
public void open();
public void close();
}
class MainBoard{
public void run(){
System.out.println("mainboard run ");
}
public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。{
if(p!=null){//判断传进来是否一个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");
method();
}
}
class SoundCard implements PCI{//声卡实现接口复写其方法
public void open(){
System.out.println("SoundCard open");
}
public void close(){
System.out.println("SoundCard close");
}
}
class DuoTaiDemo5 {
public static void main(String[] args) {
MainBoard mb = new MainBoard();//建立主板对象
mb.usePCI(new NetCard());//主板对象调用其使用PCI接口方法,然后PCI接口作为引用指向了自己的子类对象,所以在里面直接new一个匿名的子类对象作为参数传进去
mb.usePCI(new SoundCard());

}
}

内部类:

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

访问特点:

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

为什么呢?

因为内部类中持有了一个外部类的引用,格式是:外部类名.this 

2, 外部类要访问内部类,必须建立内部类对象。

格式:

外部类.内部类 变量名 外部类对象.内部类对象;

lass Outer{
private int x = 3;
private class Inner//内部类{
void function(){
System.out.println(x)//x前面省略了Outer.this.
}
void show(){
Inner in = new Inner();
In.function();
}
}

3, 当内部类存在成员位置上,就可以被成员修饰符所修饰。

例如:

1private:将内部类在外部类中封装。

2Static:内部类就具备了静态的特性,他就只能访问外部类中的静态成员,有局限了

3,子啊外部其他类中,怎么直接访问静态内部类里面的非静态成员呢?

   这样访问:new Outer.Inner().function();

4,在外部其他类中,怎么直接访问static内部类的静态成员呢?

   这样访问:Outer.Inner().function();

注意:

当内部类中定义了静态成员,该内部类必须是静态的;

当外部类中的静态方法访问内部类,该内部类也必须是静态的

什么时候使用内部类

当描述事物时,事物内部还有事物,该事物用内部类来描述;

因为内部事物在使用外部事物的内容。如心脏在人身体内,心脏可以定义成内部类。

内部类定义在局部时:

1, 不可以被成员修饰符修饰;

2, 可以直接访问外部类成员,因为还持有外部类中的作用。

但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量

例如:

  class Outer{//外部类
  int x = 3;//成员变量
  void method(final int a){//成员方法
  final int y = 4;//局部变量
  class Inner{//内部类
  void function(){//局部内部类
  System.out.println(y);// 访问被final修饰的局部变量
  }
  }
  new Inner().function();
  <span style="white-space:pre"></span>}
  }

匿名内部类:

1,就是内部类简化写法。

2前提: 内部类可以继承或实现一个外部类或者接口

3格式: 

new 外部类名或者接口名(){

      复写类或者接口中的代码,也可以自定义内容;

}

简单理解就是:建立一个带内容的外部类或者接口的子类匿名对象。

bstract class AbsDemo{//先定义一个抽象类
abstract void show();
}
class Outer{
int x = 3;
public void function(){
new AbsDemo(){//在成员方法里定义一个匿名内部类,因为没有名字所以只能用其父类名来标示,
  void show(){/复写父类的方法
  System.out.println(“匿名内部类”);/
  void abc(){
  System.out.println(“子类特有方法”);
  }.show();//调用其匿名内部类自己方法。
  }
}
}
}

思考:

AbsDemo d = new AbsDemo(){

Int num = 9;

void show(){

System.out.println(num);

};//这个怎么理解?

分析:

可能第一感觉是错误,抽象类怎么能建立对象?其实这是父类引用调用子类对象,AbsDemo d = new AbsDemo(){…};就等价于AbsDemo d = new Inner();

然后d调用其子类方法,d.show();但是对于子类特有方法abc();却是不能调用了,这个在多态时讲到了

练习:补足代码。通过匿名内部类。

nterface Inter{
void method();
}
class Test {
//补足代码区。
Public static Inter function(){
return new Inter(){
  public void method(){
  System.out.println(“run”);
  }
  };
}
}
class InnerClassTest {
public static void main(String[] args) {

Test.function().method();//重点是看懂这段代码!
//Inter in = Test.function();
//in.method();
show(new Inter(){
public void method(){
System.out.println("method show run");
}
});
}

分析:

Test.function().method()

//Test.function():Test类中有一个静态的方法function

//.method():function这个方法运算后的结果是一个对象。而且是一个Inter类型的对象。

//因为只有是Inter类型的对象,才可以调用method方法


面试题:

当没有给父类也没有接口还能写内部类吗?

分析:在main主函数里也是可以的,因为有“上帝“,是Object

<span style="font-size:18px;">lass InnerTest{
public static void main(String[] args){
new Object(){
public void function(){
System.out.println("上帝来了。");
}
}.function();
}
}</span>

异常:

概述:

其实就是程序在运行时出现不正常情况。

异常由来:

 问题是现实生活中一个具体的事物,也可以通过Java的类的形式进行描述,并封装成对象。这个就是java对不正常情况进行描述后的对象体现。

异常体系:

对于问题划分:一个是严重的,一个是非严重的;

对于严重的:java通过Error类进行描述,一般不编写针对性的代码对其进行处理。

对于非严重的:java通过Exception类进行处理。在这里面可以使用针对性的处理

ErrorException的子类名都是以父类名作为后缀名

对于异常有很多种,我们可以查阅API文档java.lang包里面的Throwable(可抛)类,他是java语言中所有错误或异常的超类!

Throwable 中的常见方法:

1, getMessage();获取异常信息,返回字符串。

2, toString();获取异常名和信息,返回字符串

3, printStackTrace();获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void

4, printStackTrace(PrintStream s)通常用该方法将异常内容保存在日志文件中,以便查阅

异常的处理格式:

try{

需要被检测的代码;

}

catch(异常类 变量){

处理异常的代码;处理方式

}

finally{

一定会被执行的语句;

}

异常声明:

throwthrows

throws用于标示函数暴露出的异常。

throw用于抛出异常对象。


区别和好处:

1, throws用在函数上,后面跟异常名;好处:便于提高安全性,让调用者进行处理,不处理就编译失败;

2, throw用在函数内,后面跟异常对象;


对多异常的处理。 

1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。

2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。

3,如果多个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 ExceptionDemo2{
public static void main(String[] args) //throws Exception自己不处理又给抛出去
  {
Demo d = new Demo();
try{
int x = d.div(5,0);
System.out.println("x="+x);
}
catch (ArithmeticException e){
System.out.println(e.toString());
System.out.println("被零除了!!");
}
catch (ArrayIndexOutOfBoundsException e){
System.out.println(e.toString());
System.out.println("角标越界啦!!");
}
catch(Exception e){
System.out.println("hahah:"+e.toString());
System.out.println("over");
}

}
}

自定义异常

自定义类继承Exception或者其子类RuntimeExceeption

1, 为了让该自定义类具备可抛性

2, 让该类具备操作异常的共性方法。

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

通过构造函数定义异常信息。

例如:

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

通过throw将自定义异常抛出。 

异常:RuntimeException

Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常。

如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。

 

如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;

对于异常分两种:

1,编译时被检测的异常。

1, 编译时不被检测的异常(运行时异常。RuntimeException以及其子类)

自定义异常时:

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

示例:

lass FuShuException extends RuntimeException{
FuShuException(String msg){
super(msg);
}
}
class Demo{
int div(int a,int b)throws Exception//throws ArithmeticException{
if(b<0)
throw new FuShuException("出现了除数为负数了");//抛出自定义异常对象
if(b==0)
throw new ArithmeticException("被零除啦");//抛出RuntimeException的子类对象
return a/b;
}
}

异常练习题:

<span style="font-size:18px;">/*
需求:编写小程序 毕老师用电脑上课,在上课时会出现电脑蓝屏,冒烟现象
分析:
1,关于蓝屏冒烟这类异常需要我们自定义异常,继承Exception即可
2,对于电脑出现问题后也会导致老师无法上课,就需要将异常转换后再抛出和无法上课异常
3,描述毕老师定义变量,对于电脑也需要定义
步骤:
1,自定义蓝屏,冒烟,无法上课异常
2,定义电脑类,对其出现各种状况的进行异常处理
3,定义老师类,构造函数初始化内容
4,main函数处理老师不能教学的异常。

*/
class BlueException extends Exception//自定义蓝屏异常
{
BlueException(String message)
{
super(message);
}
}
class SmokingException extends Exception//自定义冒烟异常
{
SmokingException(String message)
{
super(message);
}
}
class NoTeachException extends Exception//自定义无法教学异常
{
NoTeachException(String message)
{
super(message);
}
}
class Computer//定义电脑类
{

private int state = 2;//定义电脑状态
public void run()throws BlueException,SmokingException//根据出现状态抛出了两个异常
{
if (state==2)
throw new BlueException("电脑蓝屏了");
if (state==3)
throw new SmokingException("电脑冒烟了");
System.out.println("在状态1,电脑正常运行");
}
public void resetComputer()//重启电脑,状态恢复到1
{
state = 1;
System.out.println("重启电脑");
}
}
class Teacher
{
private String name;
private Computer cmp;
Teacher(String name)
{
this.name = name;
cmp = new Computer();//初始化
}
public void shangKe()throws NoTeachException
{
try
{
cmp.run();
}
catch (BlueException e)
{
cmp.resetComputer();
}
catch (SmokingException e)
{
ziXi();
throw new NoTeachException("电脑坏了无法上课");//因为电脑坏了导致无法教学异常
}
System.out.println("在状态1时电脑正常上课");
}
public void ziXi()
{
System.out.println("自习");
}
}
class LaoBiException
{
public static void main(String[] args)
{
Teacher t = new Teacher("毕老师");
try
{
t.shangKe();
}
catch (NoTeachException e)
{
System.out.println("换一台电脑");
}
}
}</span>
打印结果如图:

(6)Java面向对象之加强篇

包(package)

1, 对类文件进行分类管理

2, 给类提供剁成命名空间

3, 卸载程序文件的第一行

4, 类名的全称是 包名.类名

5, 包也是一种封装形式。

具体特点:

包与包之间进行访问,被访问的包中的类以及类中成员,需要被public修饰。

不同包中的子类还可以直接访问父类中被protected权限修饰的成员

包与包之间可以使用的权限只有两种:

public protected.

现有权限总结如图:

(6)Java面向对象之加强篇

Import (导入)

Import是简化类名

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

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

通常写import mypack.Demo

Jar

Java压缩包

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

 

创建jar

Jar –cvf mypack.jar packa packb

查看jar

Jar –xvf mypack.jar

自定义jar包的清单文件

Jar –cvfm mypack.jar mf.txt packa packb


<pre>
---------------------- 
ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------