黑马程序员_java基础3-面向对象(二)多态、异常、包

------- android培训java培训、期待与您交流! ----------

(day08)面对对象(二)***************************************************************************
@@多态: 体现,前提,好处,应用。
理解为事物存在的多种形态。动物 x = new 猫();
体现:父类的引用指向了自己的子类对象。父类的引用也可以接受自己子类的对象。
前提:必须是类与类之间有关系,继承或实现。通常存在覆盖(重写);
好处:大大提高了程序的扩展性。
弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员。
    不能访问子类特有函数,否则编译失败。想要访问子类特有函数,可以向下转型cat c = (cat)a;再调用。
特点:编译时期:看左边父类(或接口)中是否有文件中调用的方法,全有则通过,没有则失败;编译时调用的函数,父类中必须全有,否则编译失败。
      运行时期,运行的函数以右边的子类函数为先!
@@类型提升==向上转型。
Animal a = new cat();//                 byte b = 5;int i = b;//b类型提升了
想要用到cat的特有方法时,怎么办?***********
强制将父类的引用,转成子类类型。(向下转型)
cat c = (cat)a;//向下转型。将父类引用转成子类类型。
而不能Animal a = new Animal();cat c = (cat)a;//这是将父类对象转成子类类型。错误。
多态自始至终都是子类对象在做着变化。不能是父类对象。
??多态中成员变量(和静态函数)的特点:编译运行看左边,编译看父类,运行也看父类。****
多态中的成员变量和静态函数被静态绑定了,以类引用为主;
多态中的非静态函数被动态绑定了,以实例对象为主。
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("NetCar open");
 }
 public void close()
 {
  System.out.println("NetCar close");
 }
}
class SoundCard implements PCI
{
 public void open()
 {
  System.out.println("SoundCard open");
 }
 public void close()
 {
  System.out.println("SoundCard close");
 }
}
class Test
{
 public static void main(String[] args)
 {
  MainBoard m = new MainBoard();
  m.usePCI(new NetCard());
  m.usePCI(new SoundCard());
 }
}

Dao==data access object 数据访问对象。
interface Dao
{
 public void add(User user);
 public void delete(User user);
}

覆盖Object中的equals()方法
public boolean equals(Object obj)
{
 if(!(Obj instanceof Demo))
  return false;
 Demo d = (Demo)Obj;
 return this.num==d.num;
}

class Demo
{
 private int num = 4;
}
class Test
{
 public static void main(String[] args)
 {
  Demo d = new Demo();
  System.out.println(d.toString());
  System.out.println(d.getClass().getName()+"@"+Integer.toHexString(d.hashCode()));
 }
}
(day09)***************************************************************************************
@@内部类
内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
   之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类.this
2,外部类要访问内部类,必须建立内部类对象。
在外部其他类中直接访问内部类中的成员。
Outer.Inner in = new Outer().new Inner();
in.function();//或者new Outer().new Inner().function();
**类可以被私有修饰,但必须是内部类,而且内部类在外部类的成员位置上时。
外部类不可以被私有修饰。
class Outer
{ private int x = 3;
 class Inner//内部类
 {
  int x = 4
  void function()
  {
   int x = 6;
   System.out.println(x);//打印6,局部变量
   System.out.println(this.x);//打印4,成员变量
   System.out.println(Outer.this.x);//打印3,外部类的成员变量。
  }
 }
}
静态内部类:
在外部其他类中直接访问静态内部类中的非静态成员。
即当function()是非静态时
Outer.Inner in = new Outer.Inner();
in.function();
//或者new Outer.Inner().function();
在外部其他类中直接访问静态内部类中的静态成员。
即当function()是静态时
Outer.Inner in = new Outer.Inner();
in.function();
//或者直接Outer.Inner.function();
非静态内部类中不能有静态成员。==只有静态内部类才能有静态成员。***

内部类定义原则:当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。
class Body
{
 private class XinZang
 {}
 private class Stomach
 {}
}
内部类定义在局部时,不能被成员修饰符修饰。不能被static,private修饰。
可以直接访问外部类中的成员,但是不能访问它所在的局部中的变量,除非该变量被fianl修饰。
class Outer
{
 int x = 3;
 void method()
 { final int y = 4;
  class Inner
  {
   void function()
   {
    System.out.println(y);
   }
  }
 }
}
@@匿名内部类(awt中多用):内部类必须是继承一个类或实现接口。
格式:new 父类或者接口(){重写父类或接口的抽象函数,自己的特有函数}
匿名内部类就是一个匿名(没有名字)的子类对象。每个匿名对象对自己的方法只能调用一次。
匿名内部类中的方法最好不超过3个。
例1 匿名内部类由来
class Outer
{
 int x = 3;
 /*
 class Inner extends AbsDemo
 {
  public void show()
  {
   System.out.println();
  }
 }
 */
 public void function()
 {
  /*new Inner().show();*/
  //简写为 匿名内部类,如下
  new AbsDemo()
  {
   public void show()
   { 
    System.out.println();
   }
  }.show();
  //匿名子类对象.show();
 }
}
例2 匿名内部类最常用的情况!
public static void show(Inter in)
{
 in.method();
}
public static void main(String[] s)
{
 //show(匿名内部类对象)
 show(new Inter()
 {
  public void method()
  { 
   System.out.println("hehe");
  }
 }
 );

 
}
例3 面试:不写任何具体对象,直接在主函数中调用一个方法。
public static void main(String[] s)
{
 new Object()
 { 
  public void function()
  {
   System.out.println();
  }
 }.function();
}
@@异常机制
{
ArithmeticException:算数异常
OutOfMemoryError:内存溢出
ArrayIndexOutOfBoundsException:角标越界异常。
}
Throwable(printStackTrace(PrintStream s)将此throwable及其追踪输出至指定输出流
   printStackTrace(PrintWriter s)将此throwable及其追踪输出至指定PrintWriter
void   printStackTrace()将此throwable及其追踪输出至标准错误流。//异常名称+异常信息+异常出现的位置//jvm默认的异常处理机制。异常的堆栈的跟踪信息。
String   toString()返回此throwable的简短描述。//异常名称和异常信息
String   getMessage()返回此throwable的详细消息字符串//异常信息  

子类 -Error
 -Exception
异常的处理:
try{需要检查的代码}
catch(异常类 变量){处理异常的代码}
finally{一定会执行语句,一般是关闭资源的代码}
三种格式:
try-catch-finally
try-catch(可以多个catch)
try-finally
单独一个try,编译失败。

try{}里有一个return语句,那么finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
1(finally里面没有return)finally里面code会执行,执行完finally再执行try里面的return;
2(finally里面也有return)finally里面code会执行,执行完finally再执行finally里面的return;try里面的return不会执行到。
3(try里面有System.exit(0))try中执行到System.exit(0);不再执行finally里面的语句,直接退出程序。


<可能发生异常的函数>throws Exception:在功能上通过throws关键字声明了该功能可以出现异常。让调用者进行处理,不处理则编译失败。
必须在调用它的函数中进行-->如下操作
 1声明并抛出:在调用<可能发生异常的函数>的函数上throws Exception。
       比如:功能函数抛给调用它的主函数,主函数抛给jvm。jvm处理它,并结束程序。
 2捕捉并处理:try{}catch(){}finally{}
1,声明时最好声明为更为具体的异常,方便调用者<声明并抛出>或者<捕捉并处理>.
2,声明几个异常就对应有几个catch(异常类 变量)块,多个catch块中出现继承关系,父类异常放下面。

自定义异常:
一般情况下,函数内出现异常,函数上需要声明,否则编译失败。但RuntimeException类及其子类 特殊!
当在函数内部出现了throw 异常对象,那么必须要给出对应的处理动作。如下:
1,在函数内部try{可能异常语句}catch(){}finally{}处理。
2,在函数上声明让调用者处理。<函数>throws 异常类。调用者进行try catch处理或再throws抛出去。
如何自定义异常信息?
因为父类中已经把异常信息的操作都完成了,
所以子类只要在构造函数时,将异常信息传递给父类,通过super语句。
class DemoException extends Exception//自定义异常必须继承Exception
{ private int value;
 DemoException()
 { 
  Super();
 }
 DemoException(String msg)
 { 
  Super(msg);
 }
 public int getValue()
 { 
  return value;
 }
}
继承Exception或者RuntimeException的原因-->
异常体系有一个特点:异常类和异常对象都被抛出。
它们都具备可抛性,这个可抛性是Throwable这个体系中独有的特点。
只有这个体系中的类和对象才能被throws和throw操作。
throws和throw的区别?
throws使用在函数上,后面可以跟着多个异常类,用逗号隔开。
throw使用在函数内,后面跟着异常对象。
@@特殊异常类RuntimeException:
RuntimeException(NullPointerException,<Array,String>IndexOutOfBoundsException,ArithmeticException)
1,在函数内抛出RuntimeException对象,函数上可以不用声明,编译通过!
2,在函数上声明RuntimeException类,调用者可以不用处理,编译通过!
3,调用含RuntimeException异常的函数,调用者可以不用处理。编译通过!
一般情况下,函数内可能出现异常,并且内部没有进行try处理,那么函数上需要声明,否则编译失败。
但RuntimeException类及其子类 特殊!
特殊的原因:当该异常发生时,希望程序停止。因为在运行时,出现了无法继续运算的情况。希望程序停止后,对代码进行修正!
自定义异常:如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException
异常分两种:
1,编译时不被检测的异常(RuntimeException及其子类)。运行时异常。异常发生时,程序停掉。
2,编译时被检测的异常。javac 的时候。编译时异常。异常发生,可以被处理。
异常在子父类覆盖中的提体现:
1,子类覆盖父类时,如果父类的方法抛出异常。那么子类的覆盖函数只能抛出父类的异常或该异常的子类。(对于新的异常,子类方法只能内部try)
2,父类方法抛出多个异常,子类在覆盖该方法时,只能抛出父类异常的子集。
3,父类或接口中方法没有异常抛出,子类在覆盖方法时,也不能抛出异常。
 如果子类覆盖的方法发生了异常,就必须进行try处理,绝对不能抛出。
练习:
class Test
{
 public static void func()throws Exception
 {
  try
  {
   throw new Exception();
  }
  finally
  {
   System.out.println("B");
  }
 }
 public static void main(String[] s)
 {
  try
  {
   func();
   System.out.println("A");
  }
  catch (Exception e)
  {
   System.out.println("C");
  }
  System.out.println("D");
 }
}//打印BCD
例2
class test
{
 static void show()throws Exception
 {
 }
 public static void main(String[] s)throws Exception
 {
 try
 {
 //两种调用的区别
 //show();//调用show()表明可能发生异常,也可能不发生异常,下面的输出语句可能执行到,所以编译通过!
 
 throw new Exception();//表明一定会发生异常,下面的语句肯定执行不到,编译会失败。
 //类似的有,return,break,continue;
  System.out.println("A");
 }
 /*catch (Exception e)
 {
  e.printStackTrace();
 }*/
 finally
 {
  System.out.println("finally");
 }
 }
}
@@包 package import jar包
对类文件进行分类管理
给类提供多层命名空间
写在程序的第一行 package 包名;//给类的前面添加包名
类名的全称是  类 变成 包名.类名 
包也是一种封装形式

编译javac -d 包的所在目录 demo.java //这样以后调用demo类只能写  包名.demo d = new 包名.demo();
运行java 包名.demo

外部类的修饰符有两个:public 和 默认
有了包,范围变大,一个包中的类要被访问,必须有足够大的权限。所以被访问的类要被public修饰。
类共有后,被访问的成员也要共有public,才能被访问。
包与包之间进行访问:
1,被访问的包中的类以及类中的成员,需要public修饰。
2,不同包中的子类还可以直接访问父类中被protected修饰的成员。
3,包与包之间的权限:public  protected
@@权限  public protected  default  private
同一个类中 ok ok    ok     ok
同一个包中 ok ok    ok
子父类(不同包) ok ok
不同包中 ok

import 导入某一个包后,调用该包中的类文件,就可以不用写前面的包名了。
建立包名不重复,可以使用url进行定义,url是惟一的。
例如:package  cn.itcast.demo
      package  cn.tacast.test
java默认导入了 java.lang包。

jar包:  需要jar.exe来完成。
方便项目的携带
方便使用,只要在classpath设置jar路径即可
数据库驱动,SSH框架等都是以jar包体现的。
jar -cf haha.jar packa packb//将packa和packb归档到一个haha.jar包中去,。
jar -tf haha.jar //查看归档文件haha.jar下的目录
jar -tf haha.jar >c:\1.txt//将haha.jar的目录信息写在c:\1.txt中
jar -cvfm haha.jar  mymanifest myclass//使用现有的清单文件“mymanifest”并将myclass目录中的所有文件归档到haha.jar中

------- android培训java培训、期待与您交流! ----------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值