黑马程序员_面向对象2

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

继承(inherit)
1.什么是继承
当定义一个类的时候,如果发现当前类需要使用另一个类中的功能,这时当前类代表的事物是另一个类的子级的时候,就可以继承另一个类
2.怎么继承
定义类的时候可以在类名后面使用extends关键字指定继承另一个类
这时子类会得到父类中的所有成员
使用继承的类叫子类(派生类),被继承的类叫父类(超类,基类)
3.继承的特点
子类继承父类将得到父类所有的可见成员。父类不能得到子类的
一个父类可以有多个子类,一个子类只有一个父类
    可以多重继承,一个子类只有一个父类,这时子类能得到父类和父类的父类中的所有功能
4.继承的原理
在创建子类对象的时候,会先加载父类,再加载子类
先创建父类对象,再创建子类对象,创建子类对象的时候,会默认调用父类的构造函数
访问成员的时候,先找子类,再找父类
5.父类的构造函数
在构造函数的第一条语句,要么是当前类构造函数this().要么是父类的构造函数super()
如果没写this()也没写super(),那么就会自动生成一个super(),默认调用父类无参构造函数
原因:创建子类对象需要创建父类对象,没指定用哪个构造函数,默认使用父类中的构造函数
注意:如果父类没有无参的构造函数,那么定义子类的时候,必须显式声明一个构造函数,内部调用父类有参的构造函数

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class Demo {  
  2.     public static void main(String[] args) {  
  3.         new C();  
  4.         new C(123);  
  5.     }  
  6. }                               
  7. class A {  
  8.     static {  
  9.         System.out.println(1);  
  10.     }  
  11.     A() {  
  12.         System.out.println(2);  
  13.     }  
  14.     A(int i) {  
  15.         this();  
  16.         System.out.println(3);  
  17.     }  
  18. }  
  19. class B extends A {  
  20.     static{  
  21.         System.out.println(4);  
  22.     }  
  23.     B(){  
  24.         super(123);  
  25.         System.out.println(5);  
  26.     }  
  27.     B(int i) {  
  28.         this();  
  29.         System.out.println(6);  
  30.     }  
  31. }  
  32.   
  33. class C extends B {  
  34.   
  35.     static {  
  36.         System.out.println(7);  
  37.     }  
  38.     C() {  
  39.     super(123);  
  40.         System.out.println(8);  
  41.     }  
  42.     C(int i) {  
  43.         super();  
  44.         System.out.println(9);  
  45.     }  
  46. }  
上述代码的打印结果:14723568 2359
6.子类重写(override)父类的方法
当子类继承父类的时候,子类会得到父类的所有可见方法
这时子类中可以和父类定义一个一摸一样(返回值类型,方法名,参数列表)的方法,这就叫重写
当子类重写父类方法之后,再次调用时,就会调用子类的方法
重写父类方法后,如果还想调用父类的方法,那么就可以使用super.方法名调用
7.@Override(重写)
在重写父类方法的时候,最好加上这个注释
加上他之后,如果没有重写成功,就会编译报错,提高代码的安全性
8.向上转型
子类继承父类之后,将得到父类的所有功能,所以子类对象可以当作父类对象使用
注意:父类不能当作子类来用,因为子类特有的方法父类没有,子类的子类也可以当作父类来用
9.子类当父类用时,成员访问的问题
父类变量引用子类对象时
调用方法:优先找子类的(无论变量是什么类型),为了更好的支持多态
访问成员变量:就看引用是哪个类型,就在哪个类型中找。(因为一般来说变量都声明为私有,这条没什么用)
10.强制类型转换
子类对象当作父类来用时,不能通过父类变量调用父类中没有的方法
如果子类拥有该方法,那么可以把父类变量强转成子类,这种方法有可能出问题
强制类型转换时, 只要两个类有父子关系, 编译不报错. 但是如果类型不匹配: ClassCastException
检查变量a是否是B类类型:if(a instanceof B)


Object类
1.什么是Object类
Object类是所有Java类的父类,当我们定义一个类的时候,如果没有继承任何类,那么默认就是继承Object类
Object类中的所有方法,都会被任何一个Java类继承
Java语言中所有类都是Object的子类,包括数组,但是基础数据类型不是(自动装箱后的基本数据类型是Object的子类)
    int i = 123; System.out.println(i.toString());//编译出错 
2.toString()方法
返回该对象的字符串表示,Object类默认返回类名@地址,建议所有子类都重写此方法
对象在和字符串做加法运算时,也会默认调用toString方法
3.equals()
==比较两个对象的地址,判断是否是指向同一个对象
Object类中默认的equals方法比较的是地址,建议重写equals方法,可以用来比较变量指向的对象中的内容是否相同
String类的equals方法JDK中已经重写

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="white-space:pre">  </span>String str = "ddd";  
  2.     String str1 = new String("ddd");  
  3.     str.equals(str1); //返回true  
  4.     重写equals方法:  
  5. public boolean equals(Object obj) { //多态  
  6.     if(this == obj)   //如果地址相同就直接返回true  
  7.         return true;    
  8.     if(!(obj instanceof Person)) //判断是否为Person类  
  9.         return false;  
  10.     Person other = (Person)obj; //为了访问Person类的成员变量,强转Object类  
  11.     //if(this.name != other.name)  不安全,Person p1 = new Person("fal",4);Person p2 = new  Person(new String("fal"),4);  
  12.     if(this.name == null) {      //防止空指针异常  
  13.         if(other.name != null)  
  14.             return false;  
  15.     }  
  16.     else if(!this.name.equals(other.name))    
  17.         return false;  
  18.     if(this.age != other.age)  
  19.         return false;  
  20.     return true;  
  21. }  
4.finalize() //使完成,使结束
在对象生命周期结束(成为垃圾对象,并且被销毁)之后,自动调用该方法
如果我们希望在对象被销毁的时候想做一些事情,就可以重写finalize()方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class FinalizeDemo {  
  2.   
  3.     public static void main(String[] args) throws Exception {  
  4.         A a = new A();  
  5.         a = null;  
  6.           
  7.         for (int i = 0; i < 1000; i++)  
  8.             new A();  
  9.               
  10.         System.gc();            // 虚拟机在垃圾对象特别多的时候, 才会销毁, 如果我们希望立即销毁, 可以调用  
  11.         Thread.sleep(1000);     // 让程序休眠1000毫秒, 等待销毁完成  
  12.     }  
  13.       
  14. }  
  15.   
  16. class A {  
  17.     public void finalize() {  
  18.         System.out.println("对象被销毁了!!!");        // 如果该对象占用资源或者打开某个链接, 在销毁的时候就应该释放掉  
  19.     }  
  20. }  

多态
1.什么是多态
一段代码可以运行出多种形态,用父类变量引用子类对象
调用方法时引用的是哪个子类对象,就调哪个类中的方法
2.怎么使用
在定义函数的的时候,形参定义成父类类型,使用父类变量调用方法
这样就不用为每个子类定义方法调用,提高代码的复用性和可维护性

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class Driver {   
  2.     public void drive(Car car) { //多态  
  3.           
  4.         car.run();  
  5.     }  
  6. }  
  7.   
  8. class Car {  
  9.     public void run() {  
  10.       
  11.     }  
  12. }  
  13.   
  14. class Benz extends Car{  
  15.     public void run() {  //重写父类的方法  
  16.         System.out.println("this is Benz");  
  17.     }  
  18. }  
  19.   
  20. class Bmw extends Car{  
  21.     public void run() {  
  22.         System.out.println("this is Bmw");  
  23.     }  
  24. }  
  25. class  Demo{  
  26.   
  27.     public static void main(String[] args) {  
  28.       
  29.         Driver d = new Driver();  
  30.         d.drive(new Benz()); //父类引用指向子类对象  
  31.     }  
  32.   
  33. }  

抽象类
1.什么是抽象类
抽象类就是用abstract关键字修饰的类
抽象类不能创建对象,它的作用就是把若干子类中的方法抽取出来定义在父类中
抽象类可以有抽象方法,有抽象方法的类必须是抽象类
2.什么是抽象方法
抽象方法就是用abstract关键字修饰的方法
抽象方法没有方法体,只有"修饰符 返回值类型 方法名(参数列表)"
抽象方法代表子类都有这个方法,但是具体实现不同
3.什么时候使用抽象类
在多个类都有相同的方法声明,并且多个类都是某一类事物的子集时,就应该定义父类
多个子类中相同的方法,可以直接在父类中定义,子类直接继承
多个子类中不同的方法,无法在父类中定义出来,但是可以定义成抽象方法
4.继承抽象类
定义一个抽象类的子类时,必须实现所有的抽象方法,除非子类也是抽象方法
5.方法重写要求
返回值类型,方法名,参数列表都一样
重写的方法的访问权限不能小于被重写的方法 public>protected>default>private
如果子类的返回值类型是父类返回值类型的子类,也可以
子类重写时不能抛出父类没有声明的异常

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //抽象类  
  2. abstract class Student  
  3. {  
  4.     private String name;  
  5.     abstract void study();//抽象方法为子类提供模版,有抽象方法的类一定是抽象类  
  6.     public void run() //抽象类中可以定义非抽象方法  
  7.     {  
  8.           
  9.     }  
  10. }  
  11.   
  12. class BaseStudent extends Student  
  13. {  
  14.     public void study() //子类必须覆盖父类的抽象方法,否则子类也该为抽象类  
  15.     {  
  16.         System.out.println("base study");  
  17.     }  
  18. }  
  19.   
  20. class AdvStudent extends Student  
  21. {  
  22.     public void study()  
  23.     {  
  24.         System.out.println("advance study");  
  25.     }  
  26. }  
  27.   
  28. class Demo  
  29. {  
  30.     public static void main(String[] args)  
  31.     {  
  32.         /*Student是抽象的无法实例化 
  33.         Student stu = new Student(); 
  34.         */  
  35.         BaseStudent baseStu = new BaseStudent();  
  36.         AdvStudent advStu = new AdvStudent();  
  37.         baseStu.study();  
  38.         advStu.study();  
  39.     }  
  40. }  

接口
1.什么是接口
接口是一种特殊的抽象类,接口中的方法全部是抽象的(JDK8之前)
一个类只能继承一个抽象类,但是可以实现多个接口
2.接口和抽象类的区别
抽象类用abstract修饰,接口用interface定义
抽象类中可以有不抽象的方法,接口中的方法都是抽象的
抽象类用extends继承,接口用implements实现
抽象类中的方法没有默认修饰符,接口中的方法默认是被public abstract修饰的
3.什么情况下用接口,什么情况下使用抽象类
在定义一个类的时候,如果需要定义抽象方法,那么就需要使用抽象类或接口
如果该类中还有不抽象的方法,那么就只能使用抽象类
其他情况尽量使用接口,因为接口不占用继承位置,子类实现接口的同时还能继承其他类
4.实现接口
两个接口中有有方法名相同,参数列表相同,但返回值类型不同的方法时不能同时继承这两个接口
实现接口和继承抽象类相同,必须实现所有的抽象方法、
除非是抽象类,可以不实现所有的方法
接口和接口之间可以互相继承,并且可以继承多个

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. interface enter   
  2. {  
  3.     abstract void run();  
  4. }  
  5. interface enter1  
  6. {  
  7.      void play(); //abstract 可不写默认为抽象方法  
  8. }  
  9. interface enter2 extends enter,enter1 //接口可以多继承  
  10. {  
  11.     abstract void eat();  
  12. }  
  13. interface enter3  
  14. {  
  15.     abstract void sleep();  
  16. }  
  17. class Boy implements enter2,enter3 //多实现  
  18. {  
  19.     public void run() //必须覆盖接口中的抽象方法  
  20.     {  
  21.         System.out.println("running");  
  22.     }  
  23.     public void play()  
  24.     {  
  25.         System.out.println("playing");  
  26.     }  
  27.     public void eat()  
  28.     {  
  29.         System.out.println("eat");  
  30.     }  
  31.     public void sleep() //必须覆盖所有抽象方法  
  32.     {  
  33.         System.out.println("sleep");  
  34.     }  
  35. }  
  36.   
  37. class  InterfaceTest  
  38. {  
  39.     public static void main(String[] args)   
  40.     {  
  41.         Boy boy = new Boy();  
  42.         boy.sleep();  
  43.     }  
  44. }  

final 关键字
1.什么是final
final关键字可以修饰类,方法,变量
被final修饰的类,方法,变量都是最终的,不能修改的
2.final类
使用final修饰一个类,这个类就不能被继承
3.final方法
使用final修饰一个方法,这个方法就不能被重写
4.final变量
使用final修饰一个变量,这个变量就不能被赋值了(只能被赋值一次)


设计模式
1.什么是设计模式
设计模式就是类似棋谱或者共识,在编程的过程中遇到一些特别常见的问题
这些问题被前人总结归纳,经过大量实践证明之后发现的一些比较经典的做法叫做设计模式
2.单例设计模式
如果在设计一个类的时候,希望这个类只有一个对象,那么就可以使用单例设计模式
写法:
a.私有化构造函数,阻止类外创建对象
b.在内部创建一个对象,用成员变量引用
c.提供一个共有的获取对象的方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class Singleton {  
  2.        
  3.         private Singelton() { //将构造函数私有化,其他类就无法通过构造函数创建对象  
  4.           
  5.         }  
  6.         /* 
  7.         由于构造函数私有化,因此无法同过new来创建对象 
  8.         没有对象则无法调用类中的非静态方法,因此把方法声明为静态让类名直接调用返回一个对象 
  9.         */  
  10.         private static Singleton single = new Singleton();  
  11.           
  12.         public static Singleton getInstance () {  
  13.           
  14.             return single;  
  15.         }  
  16.     }  

延迟加载的单例
普通的单例设计模式,在类加载的时候就会创建对象
而有的时候只是访问了类中的某个静态成员,而没有获取对象,这样创建就浪费了内存
所以我们可以使用类加载延迟的单例设计,成员变量处不直接创建对象,在第一次调用方法时创建

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class Singleton() {  
  2.         private static Singleton lazySingle = null;  
  3.       
  4.         private Singleton() {  
  5.       
  6.         }  
  7.       
  8.         public static lazySingle getInstance() {  
  9.             if (lazySingle == null)   
  10.                 lazySingle = new Singleton();  
  11.         return lazySingleton  
  12.     }  

3.模版设计模式
在使用程序做一些事情的时候,如果每次都有一些步骤是重复的
那么就可以使用模版设计模式来精简,每次只写不同的地方
写法:
定义一个抽象类用作模版类
在其中定义一个final修饰的模版方法
在方法中把每次都一样的代码写上,每次不同的代码用抽象方法代替
使用的时候,定义类继承模版类,实现抽象方法,写上每次不同的代码

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. abstract class Templete { //定义模版类  
  2.       
  3.         public abstract void run(); //其他类需要重写这个方法用来测试时间  
  4.           
  5.         public void test() { //定义模版方法,把每次一样的步骤写在里面,每次不一样的代码用抽象方法代替  
  6.               
  7.             long time1 = System.currentTimeMillis();  
  8.               
  9.             run();  
  10.               
  11.             long time2 = System.currentTimeMillis();  
  12.               
  13.             System.out.println("time="+(time2 - time1));  
  14.         }  
  15.           
  16.     }  
  17.     class S extends Templete {  
  18.       
  19.     public void run() {  
  20.       
  21.         for (int i=0; i<2334343; i++){  
  22.           
  23.         }  
  24.           
  25.     }  
  26.     public static void main(String[] args) {  
  27.       
  28.         new S().test();  
  29.     }  
  30. }  


包package
1.什么是包
平时我们使用的类都是有包的,例如:System,String,Object,他们都是在java.lang包中
Java语言按照功能模块定义了一些包,例如lang,util,io,net,sql,awt
包就是把类分类管理,一个项目中可能会有很多泪,这时就应该定义包分类管理
2.怎么定义包
package pack;
直接用类名创建对象,默认找同一个包中的类
3.编译运行
javac -d 目录 源文件名
java 包名.类名
4.使用其他包中的类
全限定名:可以使用"包名".类名的形式使用一个其他包中的类
星号方式导入包:使用import 包名.*;导入类,这样可以导入包内的所有类 
这种导入方式会先在当前包中查找,如果没有,才去导入的包中查找
类名方式导入包:使用import包名.类名方式导入类,明确指定导入一个类
推荐使用类名导入
5.有包类和无包类之间的访问
无包的类可以使用有包的类(直接导入包即可)
有包的类无法使用无包的类(不导包访问同包的,无包的又无法导入)
6.总结
以后写类都要带包,类名和文件名同名,并加上public
导入包的时候要用类名导入
编译加上-d,运行加上包名

面向对象的总结
1.构造函数
如何定义
如何重载
如何互相调用
自动生成构造函数
2.this关键字
当作引用来引用
调用当前类构造函数
3.生命周期
什么时候销毁
4.封装
私有化成员变量
提供公共访问方法
5静态
变量
方法
6.继承
创建对象的原理
父类构造函数的调用
重写父类的方法
子类可以当作父类使用
调用方法找子类
强制类型转换
7.Object
toString()
equals()


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


访问格式:
1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中
可以直接建立内部类对象
格式:
    外部类名.内部类名 变量名 = 外部类对象.内部类对象
2.当内部类在成员位置上,就可以被成员修饰符所修饰
  比如private 将内部类在外部类中进行封装
   static:内部类就具备静态的特性:当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问限制
 外部其他类中直接访问static内部类的非静态成员方式:
new Outer.Inner().function();
 在外部其他类中,如何直接访问static内部类的静态成员方式:
注意:当内部类中定义了静态成员,该内部类必须是静态的
      当外部类中的静态方法访问内部类时,内部类也必须是静态的


内部类定义在局部时:
1.不可以被成员修饰符修饰
2.可以直接访问外部类中的成员,因为还持有外部类中的引用
  但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量


匿名内部类(定义类和建立对象封装在一起,也就是匿名子类对象):
1.匿名内部类其实就是内部类的简写格式
2.定义匿名内部类的前提
  内部类必须是继承一个类或者实现接口
3.匿名内部类的格式:new父类或者接口(){定义子类的内容}
4.其实匿名内部类就是一个匿名子类对象,可以理解为带内容的对象
5.匿名内部类中定义的方法最好不要超过3个
内部类

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class Outer  
  2. {  
  3.     private int x = 3;  
  4.     private class Inner //私有内部类  
  5.     {  
  6.         private int x =4;  
  7.         void function()  
  8.         {  
  9.             int x =5;  
  10.             System.out.println("outer:"+Outer.this.x); //访问外部类变量  
  11.             System.out.println("inner"+this.x);//内部类变量  
  12.             System.out.println(x); //局部变量  
  13.         }  
  14.     }  
  15.   
  16.     static class Inner1 //静态内部类  
  17.     {  
  18.         void function()  
  19.         {  
  20.             System.out.println("fds");  
  21.         }  
  22.         static void function1()  
  23.         {  
  24.             System.out.println("std");  
  25.         }  
  26.     }  
  27.     public void method() //提供外部方法访问内部事物,对内部事物进行封装  
  28.     {  
  29.         Inner in = new Inner();  
  30.         in.function();  
  31.     }  
  32.     void show()  
  33.     {  
  34.         class Inner2 //局部的内部类,无法定义静态  
  35.         {  
  36.             final int y = 4;  
  37.             void run()//要运行此方法必须创建Inner的对象  
  38.             {  
  39.                 System.out.println(Outer.this.x);  
  40.                 System.out.println(y);//内部类定义在局部时,只能访问final型的局部变量  
  41.             }  
  42.         }  
  43.         new Inner2().run();  
  44.     }  
  45. }  
  46.   
  47. class Test  
  48. {  
  49.     public static void main(String[] args)  
  50.     {  
  51.         Outer out =  new Outer();  
  52.         out.method();  
  53.         new Outer.Inner1().function();//外部其他类访问静态内部类的非静态成员  
  54.         Outer.Inner1.function1();//外部其他类访问静态内部类的静态成员  
  55.         new Outer().show();  
  56.     }  
  57. }  

匿名内部类

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class  InnerClassDemo  
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         new Outer().function();  
  6.     }  
  7. }  
  8. abstract class AbsDemo  //匿名对象的父类  
  9. {  
  10.     abstract void show();  
  11. }  
  12. class Outer  
  13. {  
  14.     int x = 3;  
  15.     /* 
  16.     等同于下面创建匿名对象 
  17.     class Inner extends AbsDemo //继承了一个类 
  18.     { 
  19.         void show()  //覆盖 
  20.         { 
  21.             System.out.println("show:"+x); 
  22.         } 
  23.     } 
  24.     */  
  25.   
  26.     public void function()  
  27.     {  
  28.            //new Inner().show();//创建对象  
  29.            //AbsDemo d = new AbsDemo() 多态,对象d只能调用show()  
  30.          new AbsDemo()//创建匿名内部类  
  31.         {  
  32.             void show()//匿名对象的成员方法  
  33.             {  
  34.                 System.out.println("x="+x);  
  35.             }  
  36.             void abc()  
  37.             {  
  38.                 System.out.println("fdf");  
  39.             }  
  40.         }.show();//匿名子类对象调用show()方法,一次只能调用一个成员方法  
  41.     }  
  42. }  

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


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值