Android开发入门(一)——基本语法

参考资料:《Android系统下Java编程详解》
本文摘录了该书的一些知识点,适合有面向对象编程基础的开发者。

第1章 Android基本概念
1 Android应用程序框架
每个应用程序其实是一组服务和系统,包括以下内容:
① 视图(View):丰富的、可扩展的视图集合,用来构建应用程序。包括列表(Lists)、网格(grids)、文本框(Textboxs)、按钮(Buttons),甚至是可嵌入的网页浏览器。
② 内容提供器(Content Providers):使应用程序可以访问其他应用程序(如通讯录)的数据,或共享自己的数据。
③ 资源管理器(Resource Manager):提供对于非代码资源的访问,如本地化字符串、图形和布局文件。
④ 消息管理器(Notification Manager):使得应用程序能够在状态栏显示自定义的提示信息。
⑤ 活动管理器(Activity Manager):管理应用程序的声明周期,并提供常用的导航回退功能。

2 一个标准的Android程序包括:
Activity:Activity是在Android应用开发中最频繁、最基本的模块。在Android中,Activity类中主要是与界面资源相关联。Android系统会自动记录从首页到其他页面的所有跳转记录并自动将以前的Activity压入系统堆栈,用户可以通过编程的方式删除历史堆栈中的Activity Instance。
Broadcast Intent ReceiverIntent为不同的Activity之间进行跳转提供了机制,比如当从A Activity跳转到B Activity,使用Intent实现如下:

Intent in=new Intent(A.this, B.class);
startActivity(in);

BroadcastReceiver还为各种不同的Android应用程序间进行进程间通信提供了可能。
ServiceService是一个没有用户界面的在后台运行执行耗时操作的应用组件。用户可以通过startService(Intent Service)启动一个Service,也可以偶同过Context.bindService来绑定一个Service。
Content ProviderContent Provider提供了应用程序之间的数据交换机制,一个应用程序通过实现一个Content Provider的抽象接口将自己的数据暴露出区,并且隐蔽了具体的数据存储实现。

第2章 面向对象程序设计初步
1 类包括:
属性:用来描述对象的数据元素称为对象的属性(也称为数据/状态)
方法:对对象的属性进行的操作称为对象的方法(也称为行为/操作)

2 构造器(构造方法):
在Java程序中,每个类必须至少有一个构造器。
利用构造器可以产生一个类的实例,并且提供了一个地方用来定义创建类的实例时都需要执行的初始化代码。它和类中的方法很类似,可以将构造器看作一个特殊的方法。
构造器和普通方法的区别
①修饰符:可以有访问修饰符(public,protected,private),不同的是,构造器不可以有非访问性质的修饰(abstract,final,native,static或者synchronized)。
②返回值:方法可以返回任何类型的返回值或者没有返回值,构造器没有返回值也不需要void。
③命名:构造器和类使用相同的名字

public class Food
{
    private String food_name;
    public Food(String name)
    {
        this.food_name=name;

    }
}

Food myDinner = new Food("pizza");

3 对象的创建和使用
一个对象的声明实际上只是对该类的引用,需要使用new+构造器创建对象,此时存储器会给此对象相应的存储空间。当对象被成功创建后,可以使用“对象名.对象成员”的方式访问对象成员。

4 Java源文件结构
① package语句:为了避免类名的重复,使用“包”。Sun建议使用公司Internet域名倒写来当作包名。package语句只能有0个或1个,必须放在文件开始
比如目录cn\con\farsight中的包:

package cn.com.farsight;

② import语句:import语句应该出现在package语句之后(如果有的话),类的定义之前。import语句可以有很多个。
例如:

import cn.com.farsight.college.Student;

Java编译器默认所有的Java程序引入了JDK的java.lang包中所有的类。

第3章 标识符、关键字与数据类型
1 Java注释的规则(略,等需要写文档时补充)

2 成员变量的三种初始化方式:
在声明时初始化;
在类的构造方法或其他方法中动态初始化;
默认初始化值。

3 值传递和引用传递:
在Java里只有基本类型和按照下面这种定义方式的String是按值传递,其他的都是按引用传递。就是直接使用双引号定义字符串的方式:String str="This is Java.";

第5章 数组
1 一维数组的声明:
数据类型[] 数组名 或者 数据类型 数组名[]
这种方式只是声明数组变量,没有创建真正的数组。

2 一维数组的创建:
通过new操作符来显式创建一个数组:

type[] arr_name;
arr_name=new type[length];

示例:

int[] a;
a=new int[10];

获取数组长度:数组名.length

3 初始化

int k[]=new int[5];
k[]={1,3,5,7,9};
String s;
s=new String[]{"abc","cde","efg"};

4 简单数据类型数组的内存空间
Java在内存分配时会涉及以下区域:
寄存器:在程序中无法控制。
:存放基本类型和对象的引用,但对象本身不存放在栈中,而是存放在中。
:存放用new产生的数据。
静态域:存放在对象中用static定义的静态成员
常量池:存放常量。
非RAM存储:硬盘等永久存储空间。
这里写图片描述

数组复制:b=a引用堆中同一块内存空间
这里写图片描述

5 多维数组的创建
正确的创建方式:

boolean[][] b=new boolean[10][3];
int[][] a=new int[5][];

错误的创建方式:

int[][] a=nwe int[][5];

第6章 面向对象编程进阶
1 继承:用extends进行类的继承,后面紧跟父类的类名。
在Java中,一个类只能从一个父类继承,而不能从多个类中继承。
在java.lang包中有一个Object类,这个类是所有类的顶级父类。
例如:
父类Card:

public class Card
{
    String name;
    String sex;
    String tele;
    public void setName(String theName){...}
    public String getName(){...}
    ...
}

子类friendCard:

public class friendCard extends Card
{
    String address;
    public void setAddress(String theAddress){...}
    public String getAddress(){...}
    ...
}

2 访问控制
这里写图片描述

3 super关键字
用于引用父类的成员,如属性,方法或者是构造器。
调用父类构造器:

public class FriendCard extends Card
{
    public FriendCard(String friendName)
    {
        super(friendNme);
    }
    //其他代码
}

父类必须自己负责初始化自己的状态而不是让子类来做。因此,如果子类的构造器中没有显式地调用父类的构造器,也没有在构造器中调用重载的其他构造器,则系统会默认调用父类无参数的构造器。所以父类必须定义无参数的默认构造器,否则编译器将会报错。
调用父类的属性和方法:

super.属性
super.方法()

必须是那些protected或者public的属性或方法。
super用于调用父类中的方法主要用于在子类中定义了与父类同名的属性,或进行了方法的覆盖,而又要在子类中访问父类中的同名属性或覆盖前的方法的时候。

4 this关键字
this代表其所在方法的当前对象,包括:
构造器中指该构造器所创建的新对象;
方法中调用该方法的对象;
在类本身的方法或构造器中引用该类的实例变量和方法。
也可以用this在构造器中调用构造器,例如:

public class Card
{
    String name;
    String sex;
    String tele;
    public Card()
    {
        System.out.println("Card()被调用");
    }
    public Card(String theName)
    {
        this(); //调用前面的构造器
        this.name=theName;
        System.out.println("Card(String theName)被调用");
    }
    //其他代码
}

static的含义:
static方法没有this的静态方法,不可以通过this来调用静态方法。在static方法内部不能调用非静态方法,可以在没有创建任何对象的时候通过类本身来调用static方法,这也是static方法的主要用途

5 方法的覆盖于重载
子类继承父类,对父类的方法进行改造,是覆盖。
在一个类中,如果有多个方法具有相同的名称,而有不同的参数,称为方法的重载。

6 ==和equals
用法:if(a==b) if(a.equals(b))
比较简单类型数据(如int):一定要用==进行比较
比较两个引用变量对象的值是否相等(如String):用equals进行比较
比较两个引用变量对象是否指向同一个对象:用==比较
对自定义的类:默认情况下equals方法在比较的两者指向同一个对象时返回true,所以要视情况覆盖Object或者父类中的equals方法。

7 对象初始化的过程
① 设置实例变量的值为默认值,不同的数据类型有不同的初始值
② 调用类的构造器(但是还没有执行构造方法体),绑定构造器参数
③ 如果构造器中有this()调用,则根据this()调用的参数调用相应的重载构造器,然后转到步骤⑤,否则转到步骤④
④ 除了java.lang.Object类外,调用父类中的初始化块初始化父类的属性,然后调用父类构造器,如果在构造器中有super()调用,则根据super()中的参数调用父类中相应的构造器
⑤ 使用初始化程序和初始化块初始化成员
⑥ 执行构造器方法体中的其他语句
不管用哪个构造器创建对象,初始化块都会被首先运行,然后才构造器的主体部分。

8 封装类
Java的8种基本数据类型不支持面向对象的编程机制,有时会带来不便,为了解决此类问题,Java语言引入了封装类的概念,在JDK中针对各种基本数据类型分别定义相应的引用类型,并称之为封装类
所有的封装类对象都可以向各自的构造器传入一个简单类型数据来构造:

boolean b=true;
Boolean B=new Boolean(b);

byte by='42';
Byte by=new Byte(by);

int i=123;
Integer I=new Integer(i);

封装在封装类中的值,可以通过各自的xxxValue()方法来转换成简单类型。

自动装箱:Integer iObject=100;
自动拆箱:int i=new Integer(100);

在Java中,为了节省创建对象的时间和空间,对于一些常用的对象,会将它在内存中缓存起来。比如String对象,当直接用String s="str"产生对象时,如果内存中已经存在一个使用这种方式产生的字符串对象,那么就不会再新键对象,而是直接使用已经存在的那个String对象。实际上,对于如下范围内的简单数据类型:
boolean类型的值
所有byte类型的值
在-128和127之间的short类型的值
在-128和127之间的int类型的值
在\u0000~\u007F之间的char类型的值
使用自动装箱转换成相关封装类型对象的时候,行为也和String类似。

public class TestAutoBoxing
{
    public static void main(String[] args)
    {
        Integer t1=new Integer(127);
        Integer t2=new Integer(127);
        System.out.println("t1==t2?"+(t1==t2)) //false
        Integer t3=127;
        Integer t4=127;
        System.out.println("t3==t4?"+(t3==t4)) //true
        Integer t5=128;
        Integer t6=128;
        System.out.println("t5==t6?"+(t5==t6)) //false
    }
}

第7章 高级类特性
1 static关键字
通常我们创建一个类时,是在描述这个类的外观与行为。只有用new创建类的对象,数据存储空间才被分配,其方法才供外界调用。但是有如下两种情形:第一种是只想为特定域分配单一的存储空间,不考虑究竟创建多少对象,甚至根本不用创建任何对象;另一种是,希望某个方法不与包含它的类的任何对象关联在一起,也就是说即使没有创建对象,也可以调用这个方法。通过static关键字可以满足这方面的需要
使用时,在声明类的成员如方法、属性乃至自由代码块前面加上“static”这个修饰符。
在Java中,static最常用在Java应用程序入口方法main()前面,用于修饰main()方法,表示main()方法是一个类方法。我们在指向一个应用程序的时候,解析器会寻找这个main()方法,之所以将它设置为类方法,是因为在调用这个main()方法之前,还没有任何对象存在,所以如果不将它设置为类相关的,则没有办法得到任何对象,也就无法调用main()方法。
引用static变量时:可以通过对象定位变量,也可以通过类名直接引用。

public class StaticTest
{
    static int i=27;
    public static void main(String args[])
    {
        StaticTest st1=new StaticTest();
        StaticTest st2=new StaticTest();
        System.out.println(st1.i+st2.i);//通过对象定位变量
    }
}
StaticTest.i++; //通过类名直接引用

静态方法只能调用类中的静态成员。

2 final关键字
表示它修饰的类、方法或变量不可被改变。
如果不是引用类型的变量,表示值不能改变

final int CONST_VAR=30;

如果是引用类型的变量,表示不能改变这个变量的引用

final Aclass aClass=new Aclass();

一个既是static又是final的域只占据一段不能改变的存储空间。
final方法:final关键字可以将方法锁定,以防继承类修改它的含义,确保在继承中使方法的行为保持不变,并且不会被覆盖。
例如:
父类:

public class A
{
    public final void methodA()
    {...}
    //...
}

子类:

public class B extends A
{
    public void methodA() //报错
    //如果A中的methodA是private,则这样做不会报错,因为这样B本来就不能覆盖A的方法
    {...}
}

final类:如果将final关键字放在类的定义之前,则将这个类整体定义为final。这样的类不可以被继承。final类中的方法都隐式指定为final,在final类中可以给方法添加final修饰词,但是这没意义。

3 抽象类
包含抽象方法的类叫做抽象类,抽象类不能被实例化。
在类名前加abstract关键字,就可以将一个类定义为抽象类。在抽象类中定义抽象方法是在方法返回值类型前加上关键字abstract。抽象方法只需要声明,不需要实现。

public abstract class IconShape //抽象类
{
    public abstract double iconArea();//抽象方法
}

子类继承抽象类时,语法和继承普通父类相同。
子类必须覆盖所有抽象方法才能被实例化,否则这个子类还是抽象类。
在以下一个条件成立时,类必须定义为抽象类:
① 类中至少有一个抽象方法;
② 类继承了父类中的抽象方法,但是至少有一个抽象方法没有实现;
③ 类实现了某个接口,但没有全部实现接口中的方法。
区分没有实现的方法和空方法:

public int methodA();//没有实现的方法,可以用abstract修饰
public int methodB()//空方法,不能用abstract修饰
{}

4 接口
接口是方法声明和常量值定义的集合。在接口中,没有提供任何具体的实现。一个接口可以理解为:所有实现了该特定接口的类都应该长这样。
一个类可以实现多个接口。
定义接口不用class,用interface。接口中可以定义常量但是不能有变量。接口的成员属性都会被自动加上public、static和final,而对于接口中的方法,也会自动将它们设置为public。接口中的方法只需要声明,不需要方法体, 也不需要加上关键字abstract来将它声明为抽象方法。

public interface ScreenBrightness
{
    public int DEFAULT_BRIGHTNESS=10;
    //自动加上public static final
    void brightUp();
    void brightDown();
}

实现接口要用implements,一个类只能继承一个父类,并且可以同时实现一个或多个接口,多个接口之间用“,”来分隔开,通过接口可以模拟实现多继承。
一个实现了接口的类必须实现接口的所有方法,或者将没有实现的方法定义为抽象的方法,此时类也必须为抽象类。

public class MobileSet implements ScreenBrightness,Volume
//实现两个接口,ScreenBrightnessVolumn
{
 //实现的内容
}

接口中的方法默认是public的,所以类在实现接口方法时一定要用public来修饰
接口也可以从父接口中派生,接口的继承也用extends关键字。一个接口可以继承多个接口。

public interface MobileSet extends ScreenBrightness,Volumn
{
    void showData();
    //...
}

这里写图片描述

5 多态
在Java中,对象变量是多态的,一个类型为Aclass的变量既可以指向类型为Aclass的对象,又可以指向Aclas的任何子类的对象。实际上多台的作用是消除类型之间的耦合关系。
比如Aclass派生了一个子类Bclass:

Aclass a=new Bclass();

如果一个引用类型变量声明为父类的类型,但实际引用的是子类的对象,那么该变量就不能在访问子类中添加的属性和方法。
综上,引用变量的声明类型和其实际引用对象的类型可能不一致。可以用instanceof操作符鉴别一个对象真正的类型。 它返回true或者false。
原本是子类类型的对象被声明为父类类型时,可以使用强制转换的方式回复其本来面目。

pulic void getNumber(Card c)
{
    if(c instanceof FriendCard)
    {
        FriendCard fc=(FriendCard)c; //强制转换
    }
    if(c instanceof ColleagueCard)
    {
        ColleagueCard cc=(ColleagueCard)c;
    }
}

综上,父类对象和子类对象的转换需要注意以下原则:
① 子类对象可以被视为父类的一个对象;
② 父类对象不能当成某一个子类的对象;
③ 如果一个方法的形参定义的是父类对象,那么调用这个方法时,可以使用子类对象作为形参;
④ 如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以用强制类型转换转化成子类对象的引用。在转换之前要用instanceof运算符进行判断。

6 内部类
也称为嵌套类,是定义在一个类内部的类,可以是其他类的成员,也可以在一个语句块中定义。
一个内部类的对象能够方位创建它的对象的实现,包括私有数据。
对于同一个包中的其他类来说,内部类能够隐藏起来。
匿名内部类可以方便地用在回调方法中,典型应用时图形编程中的事件处理。
可以将一个内部类定义成一个静态内部类,只要在内部类定义前加static即可。

public class Outer
{
    private int a=5;
    public class Inner
    {
        private int i=1;
        public void innerMethod()
        {
            System.out.println("a="+a+",i="+i);
        }
    }
}
public void testTheInner()
{
    Inner i=new Inner();
    i.innerMethod();
}

实例化内部类必须首先有一个外部类实例存在,然后通过外部类实例来实例化内部类。

Outer.inner in=new Outer().new Inner();

如果内部类是static的,也可以用以下方法:

Outer.inner in=new Outer().Inner();

但是,非static的内部类的成员不能声明为static类型。只有在顶层类或者static的内部类中才能声明static成员。
内部类可以用protected或private修饰,以限制在它的外部类以外的地方对它访问。
Inner类也可以定义在方法内部,或是一个类的自由块中,此时,内部类是一个局部内部类,只能在方法体或是自由块中使用。局部内部类不能有访问说明符,因为它不是外部类的一部分,但是它可以访问当前代码块内的常量以及次外部类的所有成员。在类外不能直接访问局部内部类。
匿名内部类可以看作是另一种局部内部类,它通过匿名类实现接口。如果恰好只要创建一个局部内部类的对象,可以使用匿名内部类(肯定存在于一个表达式中)。

public class AnInnerTest
{
    interface AnInfc //定义一个接口
    {
        public void printInfo();
    }
    public static void main(String[] args)
    {
        AnInnerTest a=new AnInnerTest();
        Aninfc af=a.testAn();
        af.printInfo();
    }
    public AnInfc testAn()//AnInfc为接口,此处返回该接口的一个实现类的实例
    {
        return new AnInfc()
        {
            public void printInfo()
            {
                System.out.println("anonymous class")
            }
        }
    }
}

满足下面的条件使用匿名内部类比较合适:
① 只用到类的一个实例;
② 类在定以后马上用到;
③ 类非常小;
④ 给类命名不会导致你的代码更容易理解。
使用匿名内部类的原则:
① 不能有构造方法;
② 不能定义任何静态成员,方法和类;
③ 不能是public,protected,private,static;
④ 只能创建匿名内部类的一个实例;
⑤ 一个匿名内部类一定是在一个new后面,用其隐含实现一个接口或实现一个类;
⑥ 局部内部类的所有限制都对匿名内部类生效。

7 修饰符的适用范围
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页