Java4Android学习笔记

01_Java考古学

Java4Android课程介绍

什么是Java考古学

Java发展史

总结

02_Java创世纪

书写源代码、编译、运行

在命令行窗口中,通过cd进入所写的java目录(假设所写的java程序为HelloWorld.java),运行

javac HelloWorld.java 进行编译

java HelloWorld 进行运行

03_Java基本概念

1.环境变量通常是指在操作系统当中,用来指定操作系统运行时需要的一些参数

2.环境变量通常为一系列的键值对

3.Path环境变量是操作系统外部命令搜索路径

4.classpath环境变量是类文件搜索路径

5.编译是把源代码翻译成计算机可识别的代码,

6.JRE是JAVA Runtime Environment即Java运行环境

7.编译器是把源文件翻译成虚拟机能识别的代码,JVM(JAVA虚拟机)是把.class类文件翻译成操作系统可识别的代码

04_Java的变量

什么是变量?

1.计算机是一种极度精确的机器;

2.要将信息存储在计算机当中,就必须指明信息存储的位置和所需要的内存空间;

3.在Java编程语言当中,使用声明语句来完成上述的任务;

变量的声明方法:

Java4Android学习笔记_第1张图片

变量命名需符合驼峰命名法:1、变量名应该用有意义的英文单词;2、变量名如果只有一个单词,则所有的字母小写;3、变量名如果由多个英文单词组成,则从第二个单词开始首字母大写

05_Java的基本数据类型

主要内容:

1.Java数据类型分类

2.boolean类型变量特征

3.char类型变量特征

4.数值型变量特征

1.数据类型分类

Java4Android学习笔记_第2张图片

2.布尔型变量

    ①boolean类型适用于逻辑运算,一般用于程序流程控制

    ②在Java当中boolean类型只有两种取值可能-----true和false

    eg:

        boolean b = false;

3.字符型变量

    ①char类型变量用于表示通常意义上的字符;

    ②字符是由单引号括起来的单个字符;

    eg:

        char c = 'a';

    Java字符使用Unicode字符集

4.ASCII字符集

    ①在计算机中所有的数据都需要使用二进制的数字表示;

    ②类似于a,b,c无法直接用二进制表示,所以就将所有常见的符号进行编号

    ③标准ASCII码使用7位2进制数来表示字符;

    7位2进制数可以表示所有的数字、大小写字母以及一些常见的符号(例如!,@,#$);

5.Unicode字符集

    Unicode为每种语言的每个字符设定了统一并且唯一的二进制码

    Unicode使用数字0-0x10FFFF来表示字符,最多允许有1114112个字符

    ③乱码的产生是存这个字的字符集跟取这个数的字符集不一样;

    Unicode中一个中文字符跟一个英文字符所占的空间是一样的;

06_练习课(基本数据类型的赋值与运算)

  1. 创建一个Java源文件,命名为Exerc01.java。在主函数当中创建一个boolean类型的变量,并且尝试为这个变量赋值(true,false和0),并将这个变量的值打印出来。

    Exerc01.java

    public class Exerc01 {

        public static void main(String args []){

            boolean b = true;

            System.out.println(b);

        }

    }

    编译运行

    true

  2. 创建一个Java源文件,命名为Exerc02.java。在主函数中创建一个char类型的变量,并尝试为这个变量赋值(英文字符或者中文字符),并将这个变量的值打印出来。

    Exerc02.java

    public class Exerc02 {

        public static void main(String args []){

            char c = 'a';

            //char c = '';

            System.out.println(c);

        }

    }

    编译运行

    a

  3. 创建一个Java源文件,命名为Exerc03.java。在主函数中为每一种数值型创建一个变量,并且赋值,然后进行各种加减乘除的运算。

    Exerc03.java

    public class Exerc03 {

        public static void main(String args []){

            byte b = 0;

            short s = 0;

            int i = 0;

            long l = 0;

            float f = 0;

            double d = 0;

            //float f1 = 0.1; //可能损失精度

            float f1 = 0.1F;     //正确

            //int j = 0.5*10;    //可能损失精度

            double j = 0.5*10 + 4 + 1;     //正确

            //byte k = b+0;    //可能损失精度

            byte k = (byte)(b+0); //正确

            

        }

    }

 

字面量:

整数字面量为整型(int)

小数字面量为双精度浮点型(double)

 

07_运算符与表达式

Java当中的运算符

1、算术运算符:+,—,*,%,++,——

2、关系运算符:>,<,>=,<=,==,!=

3、布尔逻辑运算符:!(逻辑非),&(逻辑与),丨(逻辑或),^(逻辑异或),&&(短路与),||(短路或)

4、位运算符:&,丨,^,~,>>,<<,>>>

5、赋值运算符:= 扩展赋值运算符:+=, —=,*=,/=

6、字符串连接运算符:+

算术运算符

要点一:

Int I = 3/2 请问i的值是几?(答案:i=1)

原因:一个运算的结果取决于所有操作数中操作数那个最大的类型。

要点二:

i++和++i的区别是什么?

i++是使用了i的值之后再将i的值加1
++i是在使用i的值之前就将i的值加1

 

Java4Android学习笔记_第3张图片

 

表达式的类型和值

表达式是符合一定语法规则的运算符和操作符的序列:

如i; 10.5+i; (i+j)-2

表达式的值

对表达式中操作数进行运算得到的结果称为表达式的值

表达式的类型:

表达式的值的数据类型即为表达式的类型

 

08_分支语句

程序运行流程的分类:顺序结构;分支结构;循环结构

Java4Android学习笔记_第4张图片

Java4Android学习笔记_第5张图片

 

Java4Android学习笔记_第6张图片

Java4Android学习笔记_第7张图片

Java4Android学习笔记_第8张图片

Java4Android学习笔记_第9张图片

default用[]括起来表示其在程序中可有可无,实际程序中用到default时不需要[]

09_练习课(二)

练习目标:熟悉if…else…结构的使用方法

练习一:将学生分数按标准分为:优、良、中、差四个级别

步骤:

  1. 创建一个名为Test01的类;
  2. 在Test01类中加入主函数;
  3. 在主函数当中定义一个整型变量,用于表示学生的分数;
  4. 使用if…else…结构对分数进行分级;

Test01.java

public class Test01 {

    public static void main(String args []){

        int score = 90;

        if(score > 85 && score <= 100){

            System.out.println("成绩为优");

        }

        else if(score > 75 && score <=85){

            System.out.println("成绩为良");

        }

        else if(score > 60 && score <=75){

            System.out.println("成绩为中");

        }        

        else if(score <= 60){

            System.out.println("成绩为差");

        }

        else if(score > 100 && score < 0){

            System.out.println("成绩不在正常范围内");

        }

            

    }

}

练习二:猜拳游戏

步骤:

  1. 创建一个名为Test02的类;
  2. 在Test02类当中加入主函数;
  3. 在主函数当中定义两个char类型的变量,分别代表两个玩家的出拳;
  4. 使用if…else…结构对结果进行判断;

Test02.java

public class Test02 {

    public static void main(String args []){

        //'a'代表石头,'b'代表剪子,'c'代表布

        char play1 = 'a';

        char play2 = 'b';

        if(play1 == 'a' && play2 == 'a'){

            System.out.println("");

        }

        else if(play1 == 'a' && play2 == 'b'){

            System.out.println("play1");

        }

        else if(play1 == 'a' && play2 == 'c'){

            System.out.println("play2");

        }

        else if(play1 == 'b' && play2 == 'a'){

            System.out.println("play2");

        }

        else if(play1 == 'b' && play2 == 'b'){

            System.out.println("");

        }

        else if(play1 == 'b' && play2 == 'c'){

            System.out.println("play1");

        }

        else if(play1 == 'c' && play2 == 'a'){

            System.out.println("play1");

        }        

        else if(play1 == 'c' && play2 == 'b'){

            System.out.println("paly2");

        }

        else if(play1 == 'c' && play2 == 'c'){

            System.out.println("");

        }

    }

}

10_循环语句

for循环执行过程

forint i = 0; i < 10; i++{

        System.out.println(i);

}

while循环执行过程:

while (i < 10)    {

    System.out.println(i);

    i++

}

11_练习课(三)

目标:熟悉java当中的for循环使用方法

练习一:打印出100——200之间的所有素数

步骤:

1、定义一个类,名为TestPrimNumber;

2、在类当中定义函数;

3、用for循环打印出所有在100——200之间的素数;

    用for循环当中,每当循环执行一次,就判断循环变量的值是否为素数,如果是,就将循环变量的当前值打印出来;

    判断n是否为素数方法:首先用2除n,如果除不尽,再用3除n,一次类推,如果从2到n-1,都无法整除n,那么n就为素数。

TestPrimNumber.java

class TestPrimeNumber{

    public static void main(String args []){

        for(int i = 100 ; i < 201 ; i++ ){

            boolean b = false;

            for(int j = 2 ; j < i-1;j++ ){

                int k = i % j;

                if(k ==0){

                    b = true;

                }

            }

            if(!b){

                System.out.println(i);

            }

        }

    }

编译运行

101

103

107

109

113

127

131

137

139

149

151

157

163

167

173

179

181

191

193

197

199

练习二:在命令行中打印出如下的图形:

步骤:

1、定义一个类,名为TestTriangle;

2、在类当中定义一个主函数;

3、使用for循环打印四行,每行一个"*"

打印四行,每一行当中都包含四个"* "

打印四行,第一行当中有一个"* "第二行当中有"* ",一次类推;

在打印"*"之前,首先要打印" "第一行当中首先打印三个" ",第二行两个,一次类推;

TestTriangle.java

class TestTriangle{

    public static void main(String args[]){

        for(int i = 1; i < 5 ; i++){

            for(int j = 0 ; j < 4 - i ; j++ ){

                System.out.print(" ");

            }

            for(int k = 0; k < i ; k++){

                System.out.print("* ");

            }

            System.out.println("");

        }

    }

}

注:print如果不加—ln代表不用换行,加—ln代表需要换行,System.out.println("")这语句代表换行

12_面向对象基础(一)

  1. 面向对象是一种编程方法,是一种思维方式,不是一种编程语言
  2. 什么是面向对象思维方法?

    首先确定谁来做,其次确定怎么做;

    首先考虑整体,其次考虑局部;

    首先考虑抽象,其次考虑具体。

总结:不要认为掌握了一门面向对象语言就是掌握了面向对象;习惯于将面向对象与现实世界做比较

13_面向对象基础(二)

1.定义类的方法

class 类名

{

    属性;

    方法;

}

属性也叫成员变量,主要用于描述类的状态;方法也叫成员方法,主要用于描述类的行为。

2.生成对象的方法

格式:类名 对象名=new 类名();

例如:Dog dog=new Dog();

Java4Android学习笔记_第10张图片

对象的本体放在堆内存中,对象的名在栈内存中    

例如Dog d=new Dog();这行代码的运行过程如下:

Java4Android学习笔记_第11张图片

Dog d在栈内存中创建了一个Dog的引用;执行new Dog ()创建了一个Dog的对象,而对象本身放在堆内存中,new用来在堆内存中开辟一块空间放真正的对象,执行new Dog()在堆内存中开辟一块空间并将生成的Dog类型的对象放在这块空间里。所以说真正的对象在堆内存中,d只是指向对象的引用。注意:d不是对象,只是代表了对象。

类与对象的关系:类是抽象的概念,对象是具体的个体。

14_面向对象基础(三)

1.对象的使用方法

使用对象调用变量和函数:

  1. 对象.变量
  2. 对象.函数()

     

例如定义Dog类

Dog.java

class Dog{

    String name;

    int age;

    String color;

 

    void jump(){

        System.out.println("jump");

    }

}

然后生成类的对象

Test.java

class Test{

    public static void main(String args []){    

        Dog d = new Dog();

        d.name = "旺财";

        d.age = 2;

        d.color = "黑色";

 

        d.jump();

        System.out.println("名字是"+d.name);

    }

}

生成多个对象

Dog d1 = new Dog();

Dog d2 = new Dog();

Java4Android学习笔记_第12张图片

只要生成对象就会用到new;堆内存中生成对象,栈内存中引用;只要见到new在堆内存中就会生成新对象,查看程序中生成了几个对象就看new出现多少次就行了

Test.java

class Test{

    public static void main(String args []){    

        Dog d1= new Dog();

        Dog d2= new Dog();

        d1.name="旺财";;

        d2.name="四喜";

 

        d1.jump();

        d2.jump();

    }

}

修改一个对象例如d1的属性是不会影响d2的属性的

2.匿名对象的使用

    可以不定义对象的引用名称,而直接调用这个对象的方法。这样的对象叫做匿名对象,例如:

        new Dog().jump();

匿名对象都是一次性的对象,因为没有名字,用完就找不到了

15_面向对象基础(四)

1.函数的重载

class A {

    void funA(){

        System.out.println("没有参数的funA函数");

    }

    void funA(int i){

        System.out.println("拥有一个整型参数的funA函数");

    }    

}

这俩函数构成了重载关系:第一这俩函数在同一个类中,第二这俩函数函数名相同,第三参数列表不同。调用哪一个funA关键看传递的参数

重载的定义

  1. 两个或者多个函数在同一个类当中
  2. 函数名相同
  3. 参数列表不同

2.构造函数

class A {

    A(){

        

    }

    void funA(){

        System.out.println("没有参数的funA函数");

    }

    void funA(int i){

        System.out.println("拥有一个整型参数的funA函数");

    }    

}

构造函数特征:没有返回值类型的定义,函数名必须跟类名相同

但是类中没有构造函数为什么也能用构造函数呢?因为编译器在编译源文件时会检查类中是否拥有构造函数,没有的话会自动加一个无参数且方法体为空的构造函数。如果类中已有构造函数,编译器就不会添加参数为空的构造函数。

构造函数作用:使用new调用构造函数可以生成对象;可以自己编写构造函数为成员变量赋初始值

Person.java

public class Person {

    Person(){

        

    }

    Person(String n,int a){

        name = n;

        age = a;

    }

    String name;

    int age;

}

Test.java

class Test {

    public static void main(String args[]){

        Person person1 = new Person("zhangsan",10);

        Person person2 = new Person("lisi",20);

        System.out.println("person1name"+person1.name+"age"+person1.age);

        System.out.println("person2name"+person2.name+"age"+person2.age);

    }

}

16_this的使用方法

主要内容:

  1. 使用this调用成员变量和成员函数
  2. 使用this调用构造函数

 

用法一:使用this调用成员变量和成员函数

Person.java

class Person {

     String name;

      

     void talk(){

         System.out.println("my name is "+this.name);

     }

}

Test.java

class Test {

    public static void main(String args []){

        Person p1 = new Person();

        p1.name = "zhangsan";

        Person p2 = new Person();

        p2.name = "lisi";

        p1.talk();

        p2.talk();

    }

}

运行结果

my name is zhangsan

my name is lisi

 

如下场合this可以省略

     void talk(){

         System.out.println("my name is "+this.name);//此处this可省略

     }

如下场合this不可以省略,函数参数是name,成员变量也叫name

     void talk(String name){

         System.out.println("my name is "+this.name);

}

这里this.namename代表成员变量的name,如果省略this的话代表参数name

this代表了调用函数的那个对象,如p1.talk(),p1调用了talk(),this就代表了p1。就像是中文中的"我"。张三说"我"时,"我"字代表张三;李四说"我"时,"我"代表李四。

用法二:使用this调用构造函数

Person.java

class Person {

     String name;

     int age;

     String address;

    

     Person(){

         System.out.println("无参数的构造函数");

     }

      

     Person(String s1,int a,String s2){

         name = s1;

         age = a;

         address = s2;

     }

     void talk(String name){

         System.out.println("my name is "+this.name);

     }

}

构造函数这样写没问题,但是调用时容易乱,应该如下写

     Person(String name,int age,String address){

         this.name = name;

         this.age = age;

         this.address = address;

}

this.name代表成员变量,等号后边的name代表参数

现在的构造函数是对Person的三个成员变量都赋值,有的时候只需要对两个成员变量赋值,再定义如下的构造函数能实现功能,但是显得重复了。

 

Person.java

class Person {

     String name;

     int age;

     String address;

      

     Person(){

         System.out.println("无参数的构造函数");

     }

 

     Person(String name,int age){

         this.name = name;

         this.age = age;

     }

      

     Person(String name,int age,String address){

         this.name = name;

         this.age = age;

         this.address = address;

     }

      

     void talk(String name){

         System.out.println("my name is "+this.name);

     }

}

 

如下写法才是合理的

Person.java

class Person {

     String name;

     int age;

     String address;

      

     Person(){

         System.out.println("无参数的构造函数");

     }

 

     Person(String name,int age){

         this.name = name;

         this.age = age;

     }

      

     Person(String name,int age,String address){

         this(name,age);//在构造函数中调用Person(String name,int age)

         this.address = address;

     }

      

     void talk(String name){

         System.out.println("my name is "+this.name);

     }

}

一个构造函数中使用this调用另一个构造函数,必须注意的是在一个构造函数this必须是第一条语句,这样的话在一个构造函数里只能调用同类的另一个构造函数,不能调用同类的另两个构造函数,也就是不能有如下写法

class Person {

     String name;

     int age;

     String address;

     Person(){

         System.out.println("无参数的构造函数");

     }

 

     Person(String name,int age){

         this.name = name;

         this.age = age;

         System.out.println("两个参数的构造函数");

     }

      

     Person(String name,int age,String address){

         this();

         this(name,age);

         this.address = address;

         System.out.println("三个参数的构造函数");

     }

      

     void talk(String name){

         System.out.println("my name is "+this.name);

     }

}

如果非得调用另外两个构造函数的话可以如下写法

class Person {

     String name;

     int age;

     String address;

      

     Person(){

         System.out.println("无参数的构造函数");

     }

     Person(String name,int age){

         this();

         this.name = name;

         this.age = age;

         System.out.println("两个参数的构造函数");

     }

      

     Person(String name,int age,String address){

         this(name,age);

         this.address = address;

         System.out.println("三个参数的构造函数");

     }

      

     void talk(String name){

         System.out.println("my name is "+this.name);

     }

}

建立如下java工程

Person.java

class Person {

     String name;

     int age;

     String address;

      

     Person(){

         System.out.println("无参数的构造函数");

     }

 

     Person(String name,int age){

         this();

         this.name = name;

         this.age = age;

         System.out.println("两个参数的构造函数");

     }

      

     Person(String name,int age,String address){

         this(name,age);

         this.address = address;

         System.out.println("三个参数的构造函数");

     }

      

     void talk(String name){

         System.out.println("my name is "+this.name);

     }

}

Test.java

class Test {

    public static void main(String args []){

        Person p1 = new Person("zhangsan",20,"beijing");

    }

}

运行结果

无参数的构造函数

两个参数的构造函数

三个参数的构造函数

17_static关键字的作用

主要内容:

  1. 静态成员变量的语法特点
  2. 静态函数的语法特点
  3. 静态代码块的语法特点

1.静态成员变量的语法特点

可以使用类名来调用(也可以用对象来调用),比如

Person.java

class Person {

     static int i;

}

Test.java

class Test {

    public static void main(String args []){

        Person.i = 10;

    }

}

 

普通的成员变量

Person p1 = new Person();

p1.i = 10;

Person p2 = new Person();

p2.i = 20;

Java4Android学习笔记_第13张图片

修改p1.i的值不影响p2.i的值

静态的成员变量

Person p1 = new Person();

Person p2 = new Person();

Person.i = 10;

Java4Android学习笔记_第14张图片

P1p2使用同一个成员变量,也就是说所有的对象使用的成员变量的值都是同一份

Person.java

class Person {

     static int i;

}

Test.java

class Test {

    public static void main(String args []){

        Person p1 = new Person();

        Person p2 = new Person();

        Person.i = 1;//此处改为p1.i=1;是一样的效果

        System.out.println("p1.i的值为"+p1.i);

        System.out.println("p2.i的值为"+p2.i);

    }

}

运行结果

p1.i的值为1

p2.i的值为1

 

2.静态函数的语法特点

可以使用类名来调用,比如

Person.java

class Person {

     static void fun(){

         System.out.println("我是静态函数");

     }

}

Test.java

class Test {

    public static void main(String args []){

        Person.fun();

    }

}

运行结果

我是静态函数

 

下边的用法是正确的

Person.java

class Person {

     String name;

     void talk(){

         System.out.println("my name is"+this.name);

     }

}

在静态函数中不能直接引用非静态的成员变量,下边的用法是错误的

class Person {

     String name;

     static void talk(){

         System.out.println("my name is"+name);

     }

}

注意:此处不能用this.name因为静态函数调用直接用"类名.函数"如Person.fun(); 这样就不存在调用函数的那个对象的问题,所以不能用this,而直接加name又解释不通,所以不能这样用。

但是如果name这个变量是静态的,如下写法就可以了

Person.java

class Person {

     static String name;

     static void talk(){

         System.out.println("my name is "+name);

     }

}

Test.java

class Test {

    public static void main(String args []){

        Person.name = "zhangsan";

        Person.talk();

    }

}

运行结果

my name is zhangsan

 

3.静态代码块的语法特点

静态代码块无需调用,只要类中含有静态代码块,装载类的时候就会调用静态代码块。静态代码块的主要作用就是为静态变量赋值

Person.java

class Person {

 

     static{

         System.out.println("静态代码块");

     }

      

     static String name;

     static void talk(){

         System.out.println("my name is "+name);

     }

}

Test.java

class Test {

    public static void main(String args []){

        Person.name = "zhangsan";

        Person.talk();

 

    }

}

运行结果

静态代码块

my name is zhangsan

 

总结:

  1. 静态成员变量只有一份;
  2. 在静态函数当中不能使用this;
  3. 静态代码块的主要作用是为静态成员变量赋值。

 

18_继承初步

主要内容:

  1. 什么是继承?
  2. 为什么要使用继承?
  3. 继承的基本语法特点

1.什么是继承?

在现实世界中,继承就是儿子得到了老子的东西;在面向对象的世界中,继承就是一个类得到了另外一个类当中的成员变量和成员方法。

Java中只支持单继承,不允许多继承。一个子类只允许继承一个父类,一个父类可以拥有多个子类。

Java4Android学习笔记_第15张图片

Person.java

class Person {

     String name;

     int age;

     void eat(){

         System.out.println("吃饭");

     }

     void introduce(){

         System.out.println("我的名字是"+name+",我的年龄是"+age);

     }

}

Student.java

class Student extends Person{

 

}

Test.java

class Test {

    public static void main(String args []){

        Student student = new Student();

        student.name = "张三";

        student.age = 16;

        

        student.eat();

        student.introduce();

    }

}

吃饭

我的名字是张三,我的年龄是16
Student继承了Person的成员变量和成员函数,还可以拥有自己的成员变量和成员函数

class Student extends Person{

    int grade;

    

    void study(){

        System.out.println("学习");

    }

}

eg:

Person.java

class Person {

      

     String name;

     int age;

      

     void eat(){

         System.out.println("吃饭");

     }

      

     void introduce(){

         System.out.println("我的名字是"+name+",我的年龄是"+age);

     }

 

}

Student.java

class Student extends Person{

    int grade;

    

    void study(){

        System.out.println("学习");

    }

}

Test.java

class Test {

    public static void main(String args []){

        Student student = new Student();

        student.name = "张三";

        student.age = 16;

        student.grade = 3;

        student.eat();

        student.introduce();

        student.study();

    }

}

运行结果

吃饭

我的名字是张三,我的年龄是16

学习

2.为什么要使用继承?

如果两个类或更多的类拥有共同的成员变量和成员函数,就可以把这些成员变量和成员函数放到父类里边去,也就是重复的代码都放到父类去,然后这子类去继承这个父类。今天这些共同的代码需要修改时,只需要在父类中进行修改即可。

使用继承是为了减少重复代码,另外子类还可以在继承父类的基础上进行扩展

子类可以继承父类的成员变量和成员函数,但是不能继承父类的构造函数

19_子类实例化过程

主要内容:

  1. 生成子类的过程
  2. 使用super调用父类构造函数的方法

1.生成子类的过程

Person.java

class Person {

      

     String name;

     int age;

      

     Person(){

         System.out.println("Person的无参数构造函数");

     }

      

     Person(String name,int age){

         this.name = name;

         this.age = age;

         System.out.println("Person的有参数的构造函数");

     }

      

     void eat(){

         System.out.println("吃饭");

     }

    

}

Student.java

class Student extends Person{

    int grade;

//在子类的构造函数中,必须调用父类的构造函数

    Student(){

        System.out.println("Student的无参数构造函数");

    }

}

Test.java

class Test {

    public static void main(String args []){

        Student student = new Student();

 

    }

}

运行结果

Person的无参数构造函数

Student的无参数构造函数

2.使用super调用父类构造函数的用法

在子类的构造函数中,必须调用父类的构造函数,无明确调用父类构造函数时,编译器会自动加一行Super();用于调用父类中无参数的构造函数,如下

class Student extends Person{

    int grade;

    Student(){

        Super();

        System.out.println("Student的无参数构造函数");

    }

}

Student从父类中继承了两个成员变量,自身有一个成员变量,要为三个成员变量赋值如果写成如下的构造函数的话,会显得跟父类中的构造函数重复

Student.java

class Student extends Person{

    int grade;

    Student(){

        System.out.println("Student的无参数构造函数");

    }

    

    Student(String name,int age,int grade){

        this.name = name;

        this.age = age;

        this.grade = grade;

    }

}

为了避免重复,可以使用supper调用父类中的构造函数,具体调用父类中的哪个构造函数由super后边的参数来决定,完整程序如下

Person.java

class Person {

      

     String name;

     int age;

      

     Person(){

         System.out.println("Person的无参数构造函数");

     }

      

     Person(String name,int age){

         this.name = name;

         this.age = age;

         System.out.println("Person的有参数的构造函数");

     }

      

     void eat(){

         System.out.println("吃饭");

     }

    

}

 

Student.java

class Student extends Person{

    

    int grade;

    Student(){

        System.out.println("Student的无参数构造函数");

    }

    

    Student(String name,int age,int grade){

        super(name,age);//一定要是这个函数的第一条语句,跟this一个道理

        this.grade = grade;

    }

}

Test.java

class Test {

    public static void main(String args []){

        Student student = new Student("zhangsan",18,3);

        System.out.println(student.name);

        System.out.println(student.age);

        System.out.println(student.grade);

    }

}

运行结果

Person的有参数的构造函数

zhangsan

18

3

20_函数的复写

主要内容:

  1. 函数的复写(override
  2. 使用super调用父类的成员函数

1.函数的复写

(override)也成覆盖或重写:①在具有父子关系的两个类当中;②父类和子类各有一个函数,这两个函数的定义(返回值类型、函数名和参数列表)完全相同。

下边的例子,标黄的部分构成了函数的复写

Person.java

class Person {

      

     String name;

     int age;

      

     void introduce(){

         System.out.println("我的姓名是"+ name+"我的年龄是"+age);

     }

    

}

Student.java

class Student extends Person{

    String address;

    

    void introduce(){

        System.out.println("我的性命是"+name+"我的年龄是"+age);

        System.out.println("我的家在"+address);

    }

}

Test.java

class Test {

    public static void main(String args []){

        Student s= new Student();

        s.name = "张三";

        s.age = 20;

        s.address = "北京";

        s.introduce();

 

    }

}

运行结果

我的性命是张三我的年龄是20

我的家在北京

2.使用super调用父类的成员函数(方法)

在函数的复写例子中两个函数存在重复,这就可以采用super调用父类的成员函数

Student.java做如下改动

class Student extends Person{

    String address;

    

    void introduce(){

        super.introduce();

        System.out.println("我的家在"+address);

    }

}

运行结果是一样的,这里super.introduce();可以不写在introduce()的第一行

可以如下写

    void introduce(){

        System.out.println("我的家在"+address);

super.introduce();

    }

21_对象的转型(很重要)

主要内容:

  1. 对象的向上转型
  2. 对象的向下转型

1.对象的向上转型

向上转型-------将子类的对象赋值给父类的引用,现实生活中比如笔记本电脑属于电脑,茶杯属于杯子。比如下边的例子:Student是Person的子类,把一个Student类型的对象s赋值给一个Person类型的引用p

Java4Android学习笔记_第16张图片

下边的例子编译会出错

Person.java

class Person {

      

     String name;

     int age;

      

     void introduce(){

         System.out.println("我的姓名是"+ name+"我的年龄是"+age);

     }

    

}

Student.java

class Student extends Person{

    String address;

    void study(){

        System.out.println("我正在学习");

    }

    void introduce(){

        super.introduce();

        System.out.println("我的家在"+address);

    }

}

Test.java

class Test {

    public static void main(String args []){

        Student s = new Student();

        Person p = s;

        

        p.name = "张三";

        p.age = 20;

        p.address = "北京"

 

    }

}

p.address = "北京";这样用是错误的,一个引用能够调用哪些成员(变量和函数),取决于这个引用的类型

将Test.java改为如下

class Test {

    public static void main(String args []){

        Student s = new Student();

        Person p = s;

        //Person p = new Student(); //这样写与上边两行一个效果

        p.name = "张三";

        p.age = 20;

        //p.address = "北京"

        p.introduce();

    }

}

运行结果为

我的姓名是张三我的年龄是20

我的家在null

从运行结果看p.introduce();这里p调用的是子类的introduce一个引用调用的是哪一个方法取决于这个引用所指向的对象

2.对象的向下转型

向下转型--------将父类的对象赋值给子类的引用

 

Java4Android学习笔记_第17张图片

向下成功的前提是先把一个对象向上转型,然后再把对象向下转型转回来,如下

Test.java

class Test {

    public static void main(String args []){

        //正确的向下转型

        Person p = new Student();

        Student s = (Student)p;

        

        //错误的向下转型

        //Person p = new Person();

        //Student s = (Student)p;

    }    

}

22_面向对象应用(一)

 

Java4Android学习笔记_第18张图片

Printer.java

class Printer {

    void open(){

        System.out.println("Open");

    }

    

    void close(){

        System.out.println("close");

    }

    

    void print(String s){

        System.out.println("print-->"+s);

    }

}

Test.java

class Test {

    public static void main(String args []){

        Printer printer = new Printer();

        printer.open();

        printer.print("abc");

        printer.close();

    }

}

运行结果:

Open

print-->abc

close

Java4Android学习笔记_第19张图片

需求:控制两台打印机,但两台打印机不是一个牌子,一个HP,一个Canon,佳能打印机有个特殊的地方,关机前会清洗一下喷头

HPPrinter.java

class HPPrinter {

    void open(){

        System.out.println("Open");

    }

    

    void close(){

        System.out.println("close");

    }

    

    void print(String s){

        System.out.println("print-->"+s);

    }

}

CanonPrinter.java

class CanonPrinter {

    void open(){

        System.out.println("Open");

    }

    

    void close(){

        this.clean();

        System.out.println("close");

    }

    

    void print(String s){

        System.out.println("print-->"+s);

    }

    

    void clean(){

        System.out.println("clean");

    }

}

Test.java

class Test {

    public static void main(String args []){

        int flag = 1;

        

        if(flag==0){

            HPPrinter hpPrinter = new HPPrinter();

            hpPrinter.open();

            hpPrinter.print("abc");

            hpPrinter.close();

        }

        else if(flag==1){

            CanonPrinter cannonPrinter = new CanonPrinter();

            cannonPrinter.open();

            cannonPrinter.print("abc");

            cannonPrinter.close();

            

        }

        

    }

}

运行结果:

Open

print-->abc

clean

close

 

HPPrinter.java与CanonPrinter.java存在重复代码,不仅如此,比如现在用户在open

打印机前需要验证用户身份,HPPrinter.java与CanonPrinter.java里的open()函数都需要修改。

修改思路:新建一个父类Printer,HPPrinter和CanonPrinter都继承这个父类

Printer.java

class Printer {

    void open(){

        System.out.println("Open");

    }

    

    void close(){

        System.out.println("close");

    }

    

    void print(String s){

        System.out.println("print-->"+s);

    }

}

HPPrinter.java

class HPPrinter extends Printer{

 

}

CanonPrinter.java

class CanonPrinter extends Printer{

    

    void close(){

        this.clean();

        super.close();

    }

    

    void clean(){

        System.out.println("clean");

    }

}

Test.java

class Test {

    public static void main(String args []){

        int flag = 1;

        

        if(flag==0){

            HPPrinter hpPrinter = new HPPrinter();

            hpPrinter.open();

            hpPrinter.print("abc");

            hpPrinter.close();

        }

        else if(flag==1){

            CanonPrinter cannonPrinter = new CanonPrinter();

            cannonPrinter.open();

            cannonPrinter.print("abc");

            cannonPrinter.close();

            

        }

 

        

    }

}

运行结果

Open

print-->abc

clean

close

Java4Android学习笔记_第20张图片

这时就比较简单了,修改代码的代价就小了,因为我们把重复代码集中到父类中去了,新建一个打印机的类去继承Printer就行

23_抽象类和抽象函数

主要内容:

  1. 抽象函数的语法特征
  2. 抽象类的语法特征
  3. 抽象类的作用

 

什么是抽象函数

    只有函数的定义,没有函数体的函数被称为抽象函数:

            abstract void fun();

 <

你可能感兴趣的:(Java4Android)