Java基础---多态、内部类、包 (黑马程序员)

来源:互联网 发布:数据库编程培训机构 编辑:程序博客网 时间:2024/06/05 10:50

第一讲     多态

        多态可以理解为事物存在的多种体现形态。

        例:动物中猫,狗。猫这个对象对应的类型是猫类型,如:猫 x = new();同时猫也是动物中的一种,也可以把猫称为动物。动物  y = new();那么动物就是猫和狗具体事物中抽取出来的父类型。父类型引用指向了子类对象。

 

一、多态的体现

       1、父类的引用指向了自己子类的对象。 

        2、父类的引用也可以接收自己的子类对象。

如:   Animal a = new Cat();

       其中就将父类型的 a引用指向了子类的对象。

 

二、多态的前提

       1、类与类之间必须有关系,要么继承,要么实现。

        2、存在覆盖。父类中有方法被子类重写。

 

三、多态的利与弊

       利:提高了程序的可扩展性和后期可以维护性。

       弊:只能使用父类中的引用访问父类中的成员。也就是说使用了多态,父类型的引用在使用功能时,不能直接调用子类中的特有方法。如:Animal a = new Cat(); 这代码就是多态的体现,假设子类Cat中有特有的抓老鼠功能,父类型的 a就不能直接调用。这上面的代码中,可以理解为Cat类型提升了,向上转型。

       如果此时父类的引用想要调用Cat中特有的方法,就需要强制将父类的引用,转成子类类型,向下转型。如:Catc = (Cat)a;

注:如果父类可以创建对象,如:Animal a = new Animal(); 此时,就不能向下转型了,Cat c = (Cat)a;这样的代码就变得不容许,编译时会报错。所以千万不能出现这样的操作,就是将父类对象转成子类类型。

        我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。多态至始至终都是子类对象在做着变化。

下面就是一个多态的示例:

[java] view plaincopy
  1. //父类————动物  
  2. abstract class Animal  
  3. {  
  4.     public abstract void eat();  
  5.   
  6. }  
  7.   
  8. //子类————猫  
  9. class Cat extends Animal  
  10. {  
  11.     //复写父类中的抽象功能  
  12.     public void eat()  
  13.     {  
  14.         System.out.println("吃鱼");  
  15.     }  
  16.   
  17.     //Cat特有的功能  
  18.     public static void catchMouse()  
  19.     {  
  20.         System.out.println("抓老鼠");  
  21.     }  
  22. }  
  23.   
  24.   
  25. class Demo  
  26. {  
  27.     public static void main(String[] args)   
  28.     {  
  29.         Animal a = new Cat();  
  30.         a.eat();  
  31.         Cat c = (Cat)a;  
  32.         c.catchMouse();  
  33.     }  
  34. }  

结果:

 

四、多态的特点

1、多态中非静态成员函数的特点

       在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。

如:在上面的示例中,如果用a.catchMouse();编译就会报错。这时只能通过强转,向下转型后,可以使用子类的特有功能。

       在运行时期:参阅对象所属的类中是否有调用的方法。这就是说,如果父类中有一个非抽象的方法,而子类继承后又将其复写了,在多态运行时,父类的引用调用这个同名函数时,被运行的将是父类中的方法。

        简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

2、多态中成员变量的特点

        无论编译和运行,都参考左边(引用变量所属的类)。如:多态中的父类引用调用成员变量时,如果父类和子类有同名的成员变量,那么被调用的是父类中的成员变量。

3、多态中静态成员函数的特点

       无论编译和运行,都参考左边。也就是父类引用在调用静态同名函数时,被调用的是父类中的静态函数。这是因为,当类一被加载,静态函数就随类绑定在了内存中。此时,不需要创建对象,就可以使用类名直接调用。同时,父类中的静态成员函数一般是不被复写的。

类在方法区中的分配:分为静态区和非静态区,而关键字thissuper在非静态区。

 

五、多态的应用

        1、定义好工具类,即将共同行为封装在一个类中。

        2、对类型进行抽取,---->多态的产生。

        3、操作同一父类型,对其中的子类型均可操作

实例小程序:

[java] view plaincopy
  1. /* 
  2. 电脑的运行实例。电脑的运行由主板控制,假设主板只是提供电脑运行,但是没有上网,听歌等功能。而上网、听歌需要硬件的支持。而现在主板上没有网卡和声卡,这时可以定义一个规则,叫PCI,只要符合这个规则的网卡和声卡都可以在主板上使用,这样就降低了主板和网卡、声卡之间的耦合性。用程序体现。 
  3. */  
  4. // 接口PCI  
  5. interface PCI  
  6. {  
  7.     void open();  
  8.     void close();  
  9. }  
  10.   
  11. //网卡实现接口  
  12. class NetCard implements PCI  
  13. {  
  14.     public void open()  
  15.     {  
  16.         System.out.println("NetCard_open");  
  17.     }  
  18.       
  19.     public void close()  
  20.     {  
  21.         System.out.println("NetCard_close");  
  22.     }  
  23. }  
  24.   
  25. //声卡实现接口  
  26. class SoundCard implements PCI  
  27. {  
  28.     public void open()  
  29.     {  
  30.         System.out.println("SoundCard_open");  
  31.     }  
  32.   
  33.     public void close()  
  34.     {  
  35.         System.out.println("SoundCard_close");  
  36.     }  
  37. }  
  38.   
  39. class Mainboard  
  40. {  
  41.     //电脑运行  
  42.     public static void run()  
  43.     {  
  44.         System.out.println("Mainboard_run");  
  45.     }  
  46.       
  47.     //使用扩展功能  
  48.     public static void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。  
  49.     {  
  50.         if(!(p==null))  
  51.         {  
  52.             p.open();  
  53.             p.close();  
  54.         }  
  55.     }  
  56. }  
  57.   
  58. class Demo  
  59. {  
  60.     public static void main(String[] args)   
  61.     {  
  62.         Mainboard m =new Mainboard();  
  63.         //电脑运行  
  64.         m.run();  
  65.           
  66.         //  m.usePCI(null);  
  67.   
  68.         //电脑上网  
  69.         m.usePCI(new NetCard());  
  70.   
  71.         //电脑听歌  
  72.         m.usePCI(new SoundCard());  
  73.     }  
  74. }  

结果:

 

第二讲     内部类

一、概述

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

        当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。如定义一个描述人的类,而手、心脏等都属于人,然它们又有自己的功能描述,这时可以在人这个描述类中,定义一个描述心脏的类,也就是内部类。

        编译时,如果代码中有内部类,生成的class文件中会含有这样的文件:Test$1.class。编译器将会把内部类翻译成用$(美元符号)分隔外部类名和内部类名的常规类文件。这是内部类的一种编译现象。

 

二、内部类的访问规则

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

             之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:  外部类名.this

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

 

三、访问格式

1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。

       格式:

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

        如:    Outer.Inner in =new Outer().new Inner();

当内部类在外部类中的成员位置上时,可以被成员修饰符所修饰。比如:

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

        static:内部类就局部static的特性。但是当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

在外部其他类中,直接访问static内部类的非静态成员的格式为:

        new外部类名.内部类名().方法名();

        如:new  Outer.Inner().function();

在外部其他类中,直接访问static内部类的静态成员格式为:

        外部类名.内部类名.方法名();

        如:Outer.Inner.function();

注意:

        1)当内部类中定义了静态成员时,该内部类必须是static的。

        2)当外部类中的静态方法访问内部类时,内部类也必须是static的。

        3)在实际应用中,内部类通常被定义为private,而很少定义为public

2、内部类定义在局部

        内部类定义在外部类中的某个方法中,创建了这个类型的对象时,且仅使用了一次,那么可在这个方法中定义局部类。

        1)不可以被成员修饰符修饰。如publicprivatestatic等修饰符修饰。它的作用域被限定在了声明这个局部类的代码块中

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

注意:内部类不可以访问它所在的局部中非最终变量。只能访问被final修饰的局部变量。

如下面的代码:

[java] view plaincopy
  1. class Outer  
  2. {  
  3.     int x = 3;  
  4.     void method(final int a)  
  5.     {  
  6.         final int y = 4;  
  7.         //局部内部类  
  8.                 class Inner  
  9.         {  
  10.             void function()  
  11.             {  
  12.                 System.out.println(y);  
  13.             }  
  14.         }  
  15.         new Inner().function();//使用局部内部类中的方法。  
  16.     }  
  17. }  
  18. class  InnerClassDemo  
  19. {  
  20.     public static void main(String[] args)   
  21.     {  
  22.         Outer out = new Outer();  
  23.         out.method(7);//打印7  
  24.         out.method(8);//打印8  
  25.     }  
  26. }  

注:为什么上面的代码中打印的值为什么会改变呢?被final修饰的变量的值是不会被改变的。这里类调用方法使用完后,这时这个被final修饰的变量已经从栈内存中消失了,类再次调用这个方法时,已经是另一变量,所以可以重新被传值。

 

四、匿名内部类

        1、匿名内部类其实就是内部类的简写格式。

        2、定义匿名内部类的前提:

             内部类必须是继承一个类或者实现接口。

             特殊情况:因为所以的类都有一个父类Object,所以在定义时也可以用Object

        3、匿名内部类的格式:  new父类或者接口(){定义子类的内容}

        4、其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。

        5、匿名内部类中定义的方法最好不要超过3个。

匿名内部类的利与弊:

        好处:简化书写

        弊端:1、不能直接调用自己的特有方法、

                     2、不能做强转动作。

                     3、如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,且调用会很麻烦。所以匿名内部类中定义的方法有一般不超过3个。

匿名内部类的应用:

[java] view plaincopy
  1. interface Inter  
  2. {  
  3.     void method();  
  4. }  
  5. class InnerClassTest   
  6. {  
  7.     public static void main(String[] args)   
  8.     {  
  9.         show(new Inter()  
  10.         {  
  11.             public void method()  
  12.             {  
  13.                 System.out.println("method show run");  
  14.             }  
  15.         });  
  16.     }  
  17.   
  18.     public static void show(Inter in)  
  19.     {  
  20.         in.method();  
  21.     }  
  22. }  


 小练习:

题目:

[java] view plaincopy
  1. interface Inter  
  2. {     
  3.     void method();  
  4. }  
  5.       
  6. class Test  
  7. {  
  8.     //补足代码,通过匿名内部类  
  9. }  
  10. class InnerClassDemo   
  11. {  
  12.     public static void main(String[] args)   
  13.     {  
  14.             Test.function().method();     
  15. }  
  16.     }  

分析:

       Test.function().method();//相当于Inter in=Test.function();in.method();

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

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

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

完整代码为:

[java] view plaincopy
  1. interface Inter  
  2. {     
  3.     void method();  
  4. }  
  5.   
  6. class Test  
  7. {  
  8.     //补足代码,通过匿名内部类  
  9.     static Inter function()  
  10.     {     
  11.         return new Inter()  
  12.         {  
  13.             public void method()  
  14.             {  
  15.                 System.out.println("内部类练习");  
  16.             }  
  17.         };  
  18.     }  
  19. }  
  20.   
  21. class InnerClassDemo   
  22. {  
  23.     public static void main(String[] args)   
  24.     {  
  25.         Test.function().method();  
  26.     }  
  27. }  

输出结果:

       


 

第四讲     

一、package

        在java中,管叫包,相当于文件夹。包里通常存放的是类文件,因为我们在编写程序的时候,难免会有类名相同的情况,就如我们人名一样。为了对类进行分类管理,java就有了包的出现,在不同包中可以有相同的类名,调用的时候连同包名一起就行。

        包也是一种封装形式。在包中可以有很多类文件,但是只提供一个类文件,供外界使用。

 

二、包的作用

        1、为避免多个类重名的情况,如果出现两个相同名字的类,可通过包将两者区分,从而避免冲突。

        2、对类文件进行分类管理,可以将相关的一些类放在同一个包中。

        3、给类提供多层命名空间,如a包中的Demo.class文件,如果要创建Demo对象,就要在使用时加上a.如:a.Demo demo=new a.Demo();

        4、包的出现可以将java的类文件和源文件相分离。

 

三、规则      

        1、包必须写在程序的第一行。因为要先有包,才知道类文件的存放地方。

        2、类的全称:包名.类名。

        3、编译定义了包的程序文件时,在编译时要指定包的存储目录。

       如:javac –d c:\mypack类名.java

 

四、包之间的访问      

        1、要访问其他包中的类,需要定义类的全称:包名.类名。

        2、包如果不在当前路径,需要使用classpath设定环境变量,为JVM指明路径。

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

        4、类中的成员权限:public或者protectedprotected是为其他包中的子类提供的一种权限。类公有后,被访问的成员也要公有才可以被访问。不同包中的子类可以直接访问父类中被protected权限修饰的成员。同一个包中,protected只作用为覆盖。

四种权限

 

public

protected

defauld

Private

同一类中

可以

可以

可以

可以

同一包中

可以

可以

可以

不可以

子类

可以

可以

不可以

不可以

不同包中

可以

不可以

不可以

不可以

注:一个.java文件里面,不能出现两个以上的公有类或者接口。因为被public修饰的类名必须与java文件名相同。

 

五、包的导入——import

        1、可以简化类名。在调用其他包中的类时,需要写类的全称,也就是连同包名一起书写。当类存在多层包中时,如:haha.hehe.pack.Demo,使用import导入后,使用其类时,就可以不加包名了。导入格式如:import haha.hehe.pack.Demo;

        2、一个程序文件中只有一个package,可以有多个importimport导入的是包中的类,不导入包中的包。

        3、注意事项:

               a,在导入包时,如果包中有很多类,可以使用通配符 *来替代包中的所有类。但是,建议不要使用通配符 *,因为将不需要使用的类导入后,会占用内存空间。所有在编写程序时,要使用包中的哪些类,就导入哪些类。

               b,定义包名不要重复,可以使用url来完成定义,url是唯一的。如:package cn.itheima.Demo

               c,导入的不同包中有相同类时,必须写类的全名以区分,否则将会报错。

 

六、jar

       类越来越多,我们可以用包来装,当包越来越多时,我们可以将包进行压缩。而java中用jar这个工具来对包进行压缩。压缩后的后缀名为jar

jar.exe工具的一些命令:

        创建jar

                jar  -cvf  mypack.jar packa packb

        查看jar

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

        解压缩

                jar  -xvf  mypack.jar

        自定义jar包的清单文件

                jarcvfm  mypack.jar mf.txt  packa packb

jar包的好处:

        1、 可以将多个包进行压缩到为一个文件。方便项目的携带。

        2、 方便于使用,只要在classpath设置jar路径,即可以执行jar包中的java程序。

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

小练习:

Demo类程序:

[java] view plaincopy
  1. package packab;//创建包packab  
  2. public class  Demo  
  3. {  
  4.     public void show()  
  5.     {  
  6.         System.out.println("Demo show");  
  7.         System.out.println("Hello World!");  
  8.     }  
  9. }  

PackDemo类程序:

[java] view plaincopy
  1. package pack;//创建pack包  
  2. import packab.Demo;//导入类Demo  
  3. public class  PackageDemo  
  4. {  
  5.     public static void main(String[] args)   
  6.     {  
  7.         new Demo().show();//使用pack包中类Demo的方法  
  8.     }  
  9. }  

结果:

      

在目录下生产的包:

      

 生成jar包命令:

      

目录中:

将两包删除,只剩下jar包。dos命令行指定classpath,然后输出的结果:

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑此网站的安全证书有问题怎么办 起诉离婚开庭时被告不到场怎么办 商标35类被别人注册了怎么办 商标被注销后被别人注册怎么办 电商35类商标被抢注怎么办 血小板太低怎么办可以吃水果吗? 微信好友删除了只记得昵称怎么办 优酷会员1080p很卡怎么办 电脑最下面的任务栏不显示怎么办 ea账号保留的问题忘了怎么办 微博超级话题账号被屏蔽怎么办 梦幻西游手机将军令号码换了怎么办 文档的内容被锁定无法修改怎么办 用户没有权限访问u盘时该怎么办? 电脑找不到ip地址连不上网怎么办 商标提前被别人注册微博昵称怎么办 扫码注册显示手机号被占用怎么办 vivo手机屏锁密码忘了怎么办 手机号注册微博手机号不用了怎么办 微博更换手机号被别人注册过怎么办 怎么有个qq注册验证码怎么办 12306手机丢了密码忘了怎么办 教师考试注册时邮箱填写错误怎么办 计算机二级注册时邮箱填错了怎么办 注册时执业范围填错了怎么办 百度号被盗了申诉不回来怎么办 斗鱼直播伴侣显示分类不可用怎么办 斗鱼黑名单显示网络加载失败怎么办 平台登录验证码只能显示一半怎么办 想改微博密码但是忘了原密码怎么办 微博账号密码都忘了怎么办 新浪博客忘记邮箱和密码忘了怎么办 新浪助学贷款邮箱密码忘了怎么办 客厅的父母乐忘记密码了怎么办 微博密码忘记了手机号也换了怎么办 想改密码旧密码忘了怎么办 商标转让转让方不配合做补证怎么办 肇事后责任方拒赔怎么办久草www 我出车祸了对方逃逸找不到人怎么办 肇事车辆怀疑是故意伤人怎么办啊 法院判的交通事故罚金没钱交怎么办