对java类的理解

 

类与对象

类有两部分组成:类声明与类体,类体可以包括成员变量和方法。

使用new运算符和类的构造方法为声明的对象分配成员变量,创建对象就是为它分配成员变量并获得一个引用,确保对象对相应成员变量的管理。

如果类中没有构造函数,系统默认一个无参构造函数。

当类创建一个对象时,成员变量被分配内存空间,这些内存空间被称为该对象的实体或变量。

Java具有垃圾回收机制:Java的运行环境会周期地检测某个实体是否已经不再被任何对象引用,如果发现这样的实体,就会释放实体占有的内存。例如:对象t1被重新构造或被t2赋值或被赋值null,原来的实例占有的内存就会被释放。

 

变量

实例变量:隶属于不同的对象,不同对象的实例变量分配不同的空间

类变量(静态变量):用关键字static修饰,该类创建的所有对象的这个变量分配给相同的内存。

常量

用final修饰,命名习惯用大写字母。不占用内存,不能被修改,所以必须被初始化。

 

方法

构造方法:专门用于创建对象,用来给出类所创建的对象的初始状态。

一个类可以重载多个构造方法(多个方法的方法名相同,但参数不同)。

实例方法:可以调用该类中的实例方法或类方法,可以操作成员变量。

类方法:用static修饰,类方法只能调用该类的类方法和操作类变量,不能调用实例方法和操作实例变量。

 

引用型数据:数组、对象、接口。变量存储的是引用(地址)而非实体。

 

 

this:表示的是当前对象,不可以出现在类方法中。

构造方法是创建对象的初始化过程,实例方法依托于对象,当然可以使用this

使用this可以区分成员变量和局部变量。

 

private修饰-私有变量和私有方法类的私有

public修饰-共有变量和共有方法  完全共有

不用修饰符-友好变量和有好方法  同一个包内可以引用

protected修饰-受保护的变量和有好方法同一个包内可以引用

子类可以继承不在同一个包中父类的protected的成员变量和方法。与调用protected的实例变量和实例方法有差异。

 

抽象类与接口

2.1基本概念

abstract classinterfaceJava语言中都是用来进行抽象类定义的,那么什么是抽象类,使用抽象类能为我们带来什么好处呢?

在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。
  在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

2.2抽象类与接口的区别

1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface
  2.abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
  3.abstract classinterface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。例如:带报警的门可以设计成本质上是报警器同时具有门的功能。继承报警器抽象类,实现门的接口。
  4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
  5.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
  6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。 
  7.接口中的方法默认都是 public,abstract 类型的。

  结论:abstract class 和 interface 是 Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概 念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。这其实也是语言的一种的惯用法,希望读者朋友能够细细体会。 

 

 

 

 

对面向对象的理解

面向对象是一种思想

一.设计步骤:

(1)程序设计首先解决的是基本类的设计(动物)――有属性和方法。

(2)实例化产生对象(人),这样动物有的属性和行为,人不用定义也可以拥有,符合自然规律。

(3)对对象进行各种操作。

二.设计意义:

通过使用面向对象的设计原则,程序员可以把一个复杂程序分成各个独立组成模块,需要具有高内聚低耦合的特性,便于设计与维护。

三.特点:

(1)封装

  封装隐藏了类的内部实现机制,可以在不影响使用者的前提下修改类的内部结构,同时保护了数据。

(2)继承

  子类继承父类就拥有了父类的属性和方法。同时子类可以重写父类的方法。

(3)多态

   相同的方法有不同的表现形式。

   i.方法重载

   在类中定义了二个或以上的相同名称方法,但它们拥有不同的参数列表。调用时需要完全相同。

   ii.方法的重写

   在子类中声明了一个和父类相同的方法,父类的方法在子类中就被覆盖了。子类重写父类的方法时访问修饰符要大于或者等于父类的,绝对不能小于。如果要在子类中调用父类被重写的方法,可以使用super.方法名(参数列表),如果不用super.方法名(参数列表),则调用的是自己重写的方法。

   iii.父类的引用指向子类的对象时
   根据指向的对象不同,同样的方法会有不同的表现。

   例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。

Animal animal1 = new Cat();或Animal animal2 = new Dog();

即声明的是父类,实际指向的是子类的一个对象。

   对象的上转型对象的实质是子类负责创建,但上转型对象失去了原对象的一些功能。上转型对象只能操作子类继承的成员变量和隐藏的成员变量、子类继承的方法或重写的方法。

//对象的上转型对象可以调用上型变量(包括被继承和被隐藏的)和下型方法(包括继承的和重写的)
//不能操作子类新增的变量和方法
//可以将上转型对象强制转换成一个子类对象。
//优点总结:可以重写方法,灵活转换,其余与上型一致。

 

4 关键字

1.super:

(1)子类使用它调用父类构造方法(子类不继承父类构造方法),默认在子类构造方法中有super();即调用父类无参构造方法。

(2)子类用它调用被子类隐藏的成员变量和方法。

2.this:

在类的实例方法中,相当于“我”,可以引用该方法当前对象。

五、修饰符

java中的修饰符分为类修饰符,字段修饰符,方法修饰符。根据功能的不同,主要分为以下几种。
1、权限访问修饰符
 public,protected,default,private,这四种级别的修饰符都可以用来修饰类、方法和字段。

可以继承的子类所在:

public:所有的

protected:自己包内+其他包中子类

default:自己包内

private:自己类中

2、final修饰符 

final的意思是不可变,他可以修饰类、字段、方法。

修饰类后类不能被继承。修饰字段后字段的值不能被改变(应该对字段进行手动初始化)。修饰方法后该方法不能被重写。

3、abstract修饰符 

abstract是抽象的意思,用来修饰类和方法。(必须重写使具体化)

修饰类后,该类为抽象类,不能被实例化,必需进行扩展。修饰方法后,该方法为抽象方法必须被子类重写(override)。

4、static修饰符 

static用来修饰内部类,方法,字段。(属于类)

修饰内部类说明该内部类属于外部类而不属于外部类的某个实例。修饰字段说明该字段属于类而不属于类实例。修饰方法说明该方法属于类而不属于类实例。

 

内部类

 

5.1 匿名内部类

匿名类是不能有名称的类,所以没办法引用它们。必须在创建时,作为new语句的一部分来声明它们。这就要采用另一种形式的new语句,如下所示: new <类或接口> <类的主体> 这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。它还创建那个类的一个新实例,并把它作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。如果匿名类对另一个类进行扩展,它的主体可以访问类的成员、覆盖它的方法等等,这和其他任何标准的类都是一样的。如果匿名类实现了一个接口,它的主体必须实现接口的方法。

java 代码

1.  interface pr    

2.  {    

3.  void print1();    

4.  }    

5.     

6.  public class noNameClass     

7.  {    

8.  public pr dest()    

9.  {    

10.    return new pr(){    

11.     public void print1()    

12.     {    

13.      System.out.println("Hello world!!");    

14.     }    

15.    };    

16.}    

17.   

18.public static void main(String args[])    

19.{    

20.    noNameClass c=new     noNameClass();    

21.    pr hw=c.dest();    

22.    hw.print1();    

23.}    

24.}    

25.   

pr也可以是一个类但是你外部调用的方法必须在你的这个类或接口中声明外部不能调用匿名类内部的方法

Java中内部匿名类用的最多的地方也许就是在Frame中加入Listner了吧。
如下:

java 代码

1.  import java.awt.*;    

2.  import java.awt.event.*;    

3.     

4.  public class QFrame extends Frame {    

5.      public QFrame() {    

6.             this.setTitle("my application");    

7.     

8.             addWindowListener(new WindowAdapter() {    

9.                     public void windowClosing(WindowEvent e) {    

10.                   dispose();    

11.                   System.exit(0);    

12.}    

13.            });      

14.   

15.          this.setBounds(10,10,200,200);    

16.     }    

17.}    

内部匿名类,就是建立一个内部的类,但没有给你命名,也就是没有引用实例的变量。
new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
             dispose();
             System.exit(0);
     }

    new 是建立一个 WindowAdapter对象 ,后面一个 {} 表示这个括号中的操作作用于这个默认的对名象,而上面的Java程序中后面是一个函数体。
这个用法的作用是:创建一个对象的实例,并且 override 它的一个函数。打开 WindowAdapter 的代码可以发现。它是一个抽象类。它是对 WindowListener 接口的一个实现。Frame.addWindowListner(); 的参数是一个 WindowListner ,而实现上是传一个从WindowAdapter 派生出的一个匿名类。

1.怎样判断一个匿名类的存在啊?看不见名字,感觉只是父类new出一个对象而已,没有匿名类的名字。

先看段伪代码
abstract class Father(){
....
}
public class Test{
   Father f1 = new Father(){ .... }  //这里就是有个匿名内部类
}
一般来说,new 一个对象时小括号后应该是分号,也就是new出对象该语句就结束了。
但是出现匿名内部类就不一样,小括号后跟的是大括号,大括号中是该new 出对象的具体的实现方法。
因为我们知道,一个抽象类是不能直接new 的,必须先有实现类了我们才能new出它的实现类。
上面的伪代码就是表示new 的是Father的实现类,这个实现类是个匿名内部类。
其实拆分上面的匿名内部类可为
class SonOne extends Father{
  ...       //这里的代码和上面匿名内部类,大括号中的代码是一样的
}
public class Test{
   Father f1 = new SonOne() ;
}

2.匿名内部类的注意事项

   注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。

在使用匿名内部类时,要记住以下几个原则:
 ?匿名内部类不能有构造方法。  
 ?匿名内部类不能定义任何静态成员、方法和类。  
 ?匿名内部类不能是public,protected,private,static。  
 ?只能创建匿名内部类的一个实例。
  ?一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。  
 ?因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

  ?内部类只能访问外部类的静态变量或静态方法。

 

匿名类和内部类中的中的this :
有时候,我们会用到一些内部类和匿名类。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名

3.匿名内部类的作用

    Java的内部类和C++中的嵌套类有本质的不同:C++的嵌套类没有指向包装类的句柄。仅仅表达一个封装的概念;但是Java的内部类不同,它可以访问包装类的成员(这表示它拥有指向包装类的句柄)。
     匿名内部类是内部类的一种简化写法:return new Wrapper {
                                        ...
                                     };
     等价于:Wrapped extends Wrapper {
          ...
          }
          return new Wrapped();

  难道匿名内部类就只这一点作用吗?
  考虑一下这样的case:

  interface ICount {
    int count();
  }
 
  class Parent {
    int i = 0;
    int count() {
      return i++;
    }
  }
       有一个类Child,它既想继承Parent的count()方法,又想实现ICount接口中的count方法,这个时候怎么办呢?内部类就可以大显身手了:
  class Child extends Parent {
    ICount getCount() {
      return new ICount {
        int i = 0;
        int count() {
         return (i *= 2);
        }
      }
    }
  }

 

 

5.2 非静态内部类和静态内部类

非静态内部类:没有无参构造器,非静态内部类必须寄生在外部类的实例中。非静态内部类不能拥有静态成员。

静态内部类:外部类相当于包,它不能访问外部类的非静态成员。【推荐使用静态内部类】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值