JAVA-面向对象

面向对象的基础篇_01
面向对象的基础篇_02
面向对象的基础篇_03

本次学习的主要内容:

01、继承性
02、对象多态性
03、final关键字
04、抽象类和接口
05、instanceof关键字
06、Object类
07、接口和抽象类的使用
08、包装类的操作
09、匿名内部类

一丶在程序的开发过程中的一些建议

  • 最基本的核心就是普通类,在以后的开发中使用最多的。
  • 当类中的某个属性需要被所有对象所共同拥有的时候就可以定义static属性。
  • 为对象实例化的时候可以考虑构造方法。
  • 程序的内容属性需要被封装。
  • 对于传递参数的命名最好要有意义,而且最好和类中的属性一一对应,就需要使用 this.属性。

二、java的三大特性

可以参考下:java面向对象的三大特性

1、封装性
2、继承性

  • 继承性是面向对象的第二大特征,主要的作用是扩充已有类的功能。
  • class 子类 extends 父类{} 。
  • 子类对父类定义的方法任意使用,子类也可以对父类中定义进行扩充。
  • 所有的私有操作private是无法直接继承的,而是通过其他的方式间接访问。
  • 一个子类只能继承一个父类,属于【单继承】,而不能同时继承多个父类。
  • class C extends A,B {} 属于多重继承,java中是不允许出现的。
  • 允许多层继承【B继承A,C继承B】。

子类对象的实例化

  • 子类对象实例化的时候实际上都会默认去调用父类中的【无参构造方法】。
super();//调用父类中的无参构造器,隐含在子类的无参构造方法中。
super(id,name);//调用父类的有参构造。

方法覆写and属性覆盖
<1>方法覆写(重写)

  • 方法名称、返回值类型、参数 完全一样就称为覆写。

  • 被覆写的方法不能拥有比父类更严格的访问控制权限。

  • 在子类中一旦方法被覆写之后,实际上最终调用的方法就是(子类)被覆写过的方法。

  • private声明的方法子类被覆写没有任何意义,访问不到。

  • 可以通过super关键字来调用父类中被子类覆写过的方法

  • 方法的覆写实际上就是根据不同的子类,同一个方法可以完成不同的功能。

<2>属性的覆盖

  • 子类声明了与父类完全一样的变量名称时,称为覆盖
class A {  
 public int value;   
 public void getValue(){   
     System.out.println("A: "+this.value);  
     System.out.println("Athis is:"+this);  
  }  
}  

//子类  
class B extends A {  
  public int value = 100;  
  public void getValue(){   
     System.out.println("B: "+this.value);  
     System.out.println("Bthis is:"+this);  
     super.getValue();  
 }  
}  

//C类,  
class C extends B {  
  public int value = 200;  
  public void getValue(){  
     System.out.println("C: "+this.value);  
     System.out.println("Cthis is:"+this);  
     super.getValue();  
 }  
} 
//这儿是调用的Main  
public class Test{  
   public static void main(String[] args) {  
       C cc = new C();  
         cc.getValue(); 
   }  
} 

//最终的输出结果是
C: 200
Cthis is:C@15db9742
B: 100
Bthis is:C@15db9742
A: 0
Athis is:C@15db9742 

<3>重载及覆写的区别

  • 重载

    • 方法名称相同,参数的类型或个数不同。
    • 没有权限要求。
    • 发生在一个类之中。
  • 覆写

    • 方法名称、参数的类型或个数、返回值相同。
    • 被覆写的方法不能拥有比父类更严格的权限。
    • 发生在继承关系中。

<4>super和this的区别

  • this

    • 调用本类中的属性或方法。
    • 可以调用本类构造,且有一个构造要作为出口。
    • 调用构造的时候一定要放在构造方法首行。
    • 表示当前对象。
  • super

    • 从子类调用父类中的属性或方法。
    • 从子类调用父类的构造方法,默认调用的是父类中的无参构造方法。
    • 放在子类构造方法首行。

使用super和this调用构造方法的语句是不可能同时出现的。

  • this会先从本类查找,如果查找到了就直接使用,查找不到,则再去父类中查找。
  • super是直接从父类中查找。

3、对象多态性
——消除类型之间的耦合关系。
——继承、重写、父类引用指向子类

对于多态性在java中有两种体现:

1、方法的重载及覆写

2、对象多态性:指的是父类对象和子类对象之间的转型操作

3、方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

4、当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。(但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了。)
5、A a = new B(); B是A的子类,B中有A类重写的方法

class A{    
      public String show(D obj){    
             return ("A and D");    
      }     
      public String show(A obj){    
            return ("A and A");    
      }     
}     
class B extends A{    
      public String show(B obj){
           return ("B and B");    
      }    
      public String show(A obj){
           return ("B and A");    
      }     
}
class C extends B{   }     
class D extends B{   } 
A a1 = new A();    
A a = new B();
B b = new B();
C c = new C();     
D d = new D();
System.out.println(a1.show(b));    
System.out.println(a1.show(c));    
System.out.println(a1.show(d));
//A and A
//A and A
//A and D
System.out.println(a.show(b));
System.out.println(a.show(c));
System.out.println(a.show(d));
//B and A
//B and A
//A and D
System.out.println(b.show(b));    
System.out.println(b.show(c));
System.out.println(b.show(d));
//B and B
//B and B
//A and D

①优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
② a.show(b) : a是一个引用变量,类型为A,则this为a,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到;于是到A的super(父类)找,而A没有父类,再找this.show((super)O),this仍然是a,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为”B and A”。

  • 向上转型(子->父):父类名称 父类对象=子类实例;【自动完成】
    • 实际上指的就是一个子类变为父类接收,但是调用的方法肯定是被子类所覆写过的操作。
进行向下转型之前必须首先发生向上转型的关系,建立关系。
要以父类所规定的方法为主,子类最好不要任意的扩充。
  • 向下转型(父->子):子类名称 子类对象=(子类名称)父类实例;【强制完成】

三丶final关键字

  • 在Java中可以使用 final 关键字定义类、方法、属性。注意以下情况:
    • final定义的类不能有子类。
    • final声明的方法不能被子类所覆写。
    • final声明的变量即成为常量。
      • 常量必须在声明时给出具体的内容。
public static final String NAME="houzi";
//声明一个全局常量

四丶抽象类和接口

<1>抽象类
1.使用abstract关键字进行声明的类是抽象类。

2.抽象方法:只声明而未定义方法体的方法称为抽象方法,抽象方法也必须使用abstract关键字声明。

abstract class Demo { // 抽象类
    public void print(){
        System.out.println("Hello World!!!") ;
    }
    public abstract void fun() ; // 抽象方法
}

3.抽象类的使用时有要求的:

①、抽象类不能直接实例化。

②、抽象类必须有子类,子类(如果不是抽象类)的话,则必须覆写抽象类中的全部抽象方法。

  • 一个子类只能继承一个抽象类。

  • 所以-抽象类不能用final声明。

③、如果一个抽象类中没有任何一个抽象方法,依然是抽象类。

④、抽象类中可以存在构造方法,依然符合于子类对象的实例化过程的要求。

⑤、抽象类和普通类相比,只是增加了抽象abstract的声明,增加了抽象方法。

<2>接口

  • 前提:一个类中全部是由抽象方法和全局常量组成。

  • 要求:接口使用interface关键字声明。

  • 接口中的方法全部都属于公共的方法操作(public)。

  • 一个接口可以同时通过 extends 关键字继承多个接口。

    • interface C extends A,B{}

一个接口定义完成之后,实际上与抽象类的使用原则是一样的:

1、接口必须有子类,子类(如果不是抽象类)则必须覆写接口中的全部抽象方法。

2、接口是不能直接进行对象的实例化操作。

3、一个子类可以同时继承(实现)多个接口,如下所示:

  • class子类implements 接口A, 接口B,…{}
interface Demo{ // 接口
    public static final String INFO = "hello world" ;
    public abstract void print() ;
}
与
interface Demo{ // 接口
                        String INFO = "hello world" ;
                    void print() ;
}
是一样的

※ 一个接口中可以定义其他的接口、抽象类或普通类。

※ 一个抽象类可以定义内部的接口、类或抽象类。

※ 对于一个内部接口使用static声明之后成为外部接口

五丶instanceof 关键字

  • instanceof 关键字可以判断某一个对象是否是某一个类的实例。
  • 在向下转型的操作之前,需要先验证的操作
class A {                 }
class B extends A {       }
public class InstanceDemo {
    public static void main(String args[]){
        A a = new A();
        System.out.println(a instanceof A);//true
        System.out.println(a instanceof B);//false
    }
}

六丶Object 类

  • Object类有12个成员方法:
    • clone()函数的用途是用来另存一个当前存在的对象。
    • equale()用于确认两个对象是否相同。
    • hashCode()返回的对象的地址值。
    • toString()返回一个String对象,用来标识自己。
    • getClass()返回一个Class对象。
    • wait()用于让当前线程失去操作权限,当前线程进入等待序列。
    • wait(long)
    • notify()用于随机通知一个持有对象的锁的线程获取操作权限。
    • notifyAll()用于通知所有持有对象的锁的线程获取操作权限。
    • wait(long)和wait(long,int)用于设定下一次获取锁的距离当前释放锁的时间间隔。
    • finalize()这个函数在进行垃圾回收的时候会用到,匿名对象回收之前会调用到。

七丶接口和抽象类的使用

  • 1丶抽象类和接口都不能直接实例化。如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象;接口变量必须指向实现所有接口方法的类对象。
  • 2丶抽象类要被子类继承,接口要被类实现。
  • 3丶接口只能做方法声明,抽象类中可以做方法声明,也可以做方法实现
  • 4丶接口里定义的变量只能是公共的静态的常量;抽象类中的变量是普通变量。
  • 5丶抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类也必须被定义成抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
  • 6、抽象方法只能声明,不能实现。接口是设计的结果,抽象类是重构的结果。
  • 7、抽象类里可以没有抽象方法。
  • 8、如果一个类里有抽象方法,那么这个类只能是抽象类。
  • 9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
  • 10、接口可继承接口,并可多继承接口,但类只能单根继承。

抽象类
|-可以有默认的方法实现
|-子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。
|-抽象类可以有构造器
|-除了你不能实例化抽象类之外,它和普通Java类没有任何区别
|-抽象方法可以有public、protected和default这些修饰符
|-抽象方法可以有main方法并且我们可以运行它
|-抽象方法可以继承一个类和实现多个接口
|-它比接口速度要快
|-如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。
|-抽象类的使用
• 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类。如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。

接口
|-子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现。
|-接口不能有构造器。
|-接口方法默认修饰符是public。
|-接口没有main方法,因此我们不能运行它。
|-接口只可以继承一个或多个其它接口。
|-接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
|-如果你往接口中添加方法,那么你必须改变实现该接口的类。
|-接口的使用:
• 一个接口仅仅是一个对象的方法的声明,具体的实现并不由接口来做。在接口中,我们定义一个对象可以执行什么样的操作。这些操作方法由实现该接口的类来实现。接口可以看作是一个类和外部环境之间的联系。外部环境通过接口可以知道一个对象可以向外部环境提供什么样的操作。实现多重继承,那么你必须使用接口。

八丶包装类

在 Java 中一直提倡:一切皆对象。基本数据类型不是类,所以为了可以让基本数据类型变为类的形式进行操作的话,在 Java 中引入了包装类的概念,可以通过包装类完成基本数据类型的封装。

在 Java 中一共定义了八种基本数据类型:int (Integer)、char(Character)、float (Float)、double(Double)、long(Long)、short(Short)、byte(Byte)、boolean(Boolean)

  • 需要注意的是,以上的八种包装类也分为两种类型:
    • 数值型:指的是 Number 的子类,有:Integer、Float、Double、Long、Short、Byte。(在 Number 类中规定了一系列的 xxxValue()方法,可以将被包装的数字取出,变回基本数据类型。)
    • 对象型:指的是 Object 的子类,有:Character、Boolean

1、装箱和拆箱(JDK1.5 增加了自动 装箱和拆箱 的操作)
装箱:将一个基本数据类型变为包装类称为装箱操作,装箱的方法由各个子类完成。
拆箱:将一个包装类变回基本数据类型,称为拆箱操作,转换的方法由 Number 类提供。
下边是一个自动装箱和拆箱的一段代码:

public class WrapperDemo{
    public static void main(String args[]){
        Float temp = 10.3f;//自动装箱
        //Object obj = 10.3f;//基本-->包装-->变为Object\
        //先自动拆箱,之后计算再装箱
        System.out.println(temp * temp) ;
        float x = temp;//自动拆箱
    }   
}

2、数据转换
包装类的最大好处是可以将字符串中的数据变为基本数据类型。

String str = "133" ;
int x = Integer.parseInt(str) ; // 将字符串变回基本数据类型
float x = Float.parseFloat(str) ;  // 将字符串变回基本数据类型

上述操作中:字符串中的内容必须完全由数字组成。

3、为了保证接收,只能通过Object接收:

  • int–>Integer–>Object
  • float–>Float–>Object
  • String–>Object
//整数型int(整数型的全拼Integer)
p.setX(10);//int-->Integer-->Object
p.setY(30);//int-->Integer-->Object
int x = (Integer) p.getX();//Object-->Integer-->int
int y = (Integer) p.getY();//Object-->Integer-->int
System.out.println("X 的坐标:" + x);
System.out.println("Y 的坐标:" + y);

九丶匿名内部类

通过两个代码来查看内部类的好处。

interface X{
    public void print();
    }
class A implements X {
    public void print(){
        System.out.println("Hello World!!!");
    }
}
class Demo {
    public void fun(X x){
            x.print();
    }
    public void hello(){
            this.fun(new A());
    }
}
public class NoInner00{
    public static void main(String args[]){
            new Demo().hello();
    }
}

只使用一次的话,那么没有必要将其定义成一个具体的类。

interface X{
    public void print();
    }
class Demo {
    public void fun(X x){
    x.print();
}
public void hello(final String info){
        this.fun(new X(){
            public void print(){
                System.out.println(info);
            }
        });
    }
}
public class NoInner01{
    public static void main(String args[]){
            new Demo().hello("Hello World!!!");
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值