(java编程思想Ⅰ)2019.6.28 一至七

抽象类 接口
抽象类 接口区别
1,抽象类里可以有构造方法,而接口内不能有构造方法。
2,抽象类中可以有普通成员变量,而接口中不能有普通成员变量。
3,抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有
非抽象的普通方法。
4,抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽
象方法只能是public类型的,并且默认即为public abstract类型。
5,抽象类中可以包含静态方法,接口内不能包含静态方法。
6,抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可
以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。
7,一个类可以实现多个接口,但只能继承一个抽象类。

Think in Java

第二章 一切都是对象

2.2 基本类型

类型位数+范围
boolean(Boolean)
char(Character)16bits 0~2^16-1(65535)
byte(Byte)8bits -128~127
short(Short)16bits -2^ 15(32768) ~ 2^15-1
int(Integer)32bits -2^31(2147483648 =2*10 ^9) ~ 2 ^31-1
long(Long)64bits -2^63(9,223,372,036,854,775,808)~ 2 ^63-1
float(Float)32bits
double(Double)64bits
void

第三章操作符

3.8 逻辑操作符(p46)

  • 短路:一旦能明确无误的确定整个表达式的值,就不再计算其余部分
 teat1(0) &&  teat1(0) && teat1(0)

3.9 直接常量(47):
后缀字符标志类型:(大小)L代表long;(大小写)F代表float;D代表double。0x代表十六进制,0代表8进制,二进制通过Integer.toBinaryString()、Long.toBinaryString()

		long i = 0x12;
       long j = 012;

       System.out.println("i="+i+"二进制"+Long.toBinaryString(i));
       System.out.println("j="+j+"二进制"+Long.toBinaryString(j));
  • 指数计数法
        float a =  1e-43f;
        float fmax = Float.MAX_VALUE;
        float fmin = Float.MIN_VALUE;
        double dmax = Double.MAX_VALUE;
        double dmin = Double.MIN_VALUE;
        System.out.println(fmax);
        System.out.println(fmin);
        System.out.println(dmax);
        System.out.println(dmin);

3.10 按为操作符(49)
&(按位与) 可与=连用
|(按位或) 可与=连用
^(按位异或) 可与=连用
~(按位非,一元操作符,) 不可与=连用
布尔类型也作为单比特值对待


        int a = 0xAAAA;
        int b = 0x5555;
        System.out.println(a&b);
        System.out.println(Integer.toBinaryString(a&b));
        System.out.println(a|b);
        System.out.println(Integer.toBinaryString(a|b));
        System.out.println(a^b);
        System.out.println(Integer.toBinaryString(a^b));

3.11 移位操作符(49)
<<(左移) 后面补0
.>>(有符号右移) 符号+,高位插入0;符号-,高位插入1
.>>>(无符号右移)高位插入0

  • 对char、byte、short类型移位,会先转换为int型,得到的结果也是int类型
    (在对byte,short移位时,先转换为int进行移位,然后再截赋值给原来的值)
    (负数的二进制是补码,原码:负数绝对值的二进制,并令最高位为1;反码:除最高位其他取反 补码:反码+1)
 int a = -1;
        System.out.println(Integer.toBinaryString(a).length());
        a>>>=10;
        System.out.println(Integer.toBinaryString(a).length());

        long b =-1;
        System.out.println(Long.toBinaryString(b).length());
        b>>>=10;
        System.out.println(Long.toBinaryString(b).length());

        short c =-1;
        System.out.println(Integer.toBinaryString(c).length());
        c>>>=10;
        System.out.println(Integer.toBinaryString(c).length());

        byte d = -1;
        System.out.println(Integer.toBinaryString(c).length());
        System.out.println(Integer.toBinaryString(c>>>10).length());

习题12:所有位都是1

int a = -1;
        a <<=10;
        System.out.println(Integer.toBinaryString(a));
        for(int i=0;i<32;i++){
            a>>>=1;
            System.out.println(Integer.toBinaryString(a));
        }
char c = 'a';
        System.out.println(Integer.toBinaryString(c));
        c+=1;
        System.out.println(Integer.toBinaryString(c));
        c = 'b';
        System.out.println(Integer.toBinaryString(c));

3.12 三元操作符

boolean-exp? value0 : value1

3.13 字符串操作符+、+=

变为字符型

int x=0,y=1,z=2;
        String s = "x,y,z";
        System.out.println(s+x+y+z);
        s += "sssss";
        System.out.println(s+(x+y+z));
        System.out.println(" "+x);
        //int====String
        String a = ""+x;
        String b = Integer.toString(x);

3.15 类型转换操作符

int a =1;
        long b=123131231;
        a = (int)b;
        b = (long)a;

3.16 截尾和舍入
对于float和double,转换为int型,回直接截尾,输出整数部分;想要舍入的话,需要round方法

float a = 1.734f;
        System.out.println((int)a);
        System.out.println(Math.round(a));

第四章 控制执行流程

  • 4.1 if-else
  • 4.3 迭代
    while(){}
    do{}while()
    for()
    求素数
static void sushu(){
        for(int i=1;i<100;i++){
            for(int j=1;j<Math.sqrt(i);j++){
                if(i%j==0 && j!=1){
                    break;
                }else if(j+1>Math.sqrt(i)){
                    System.out.println(i);
                }
            }
        }
    }
  • Foreach语法
int [] a = {1,2,3,45,6};
        for(int x :a){
            System.out.println(x);
        }
  • return:1.指定方法返回什么值;2.导致当前方法的退出
static int test(int testval,int begin,int end){
        if (end < begin) {
            System.out.println("error");
            return 0;
        }
        if(testval>=begin && testval<=end){
            return 1;
        }else{
            return -1;
        }
    }
  • 4.6 break和continue
    break:直接跳出整个循环;continue:跳出本次循环,进行下一次
    带标签的(因为有循环嵌套存在,想从多层嵌套中break或continue)
    continue label:中断所有的迭代,直接转到label的地方,然后继续程序
    break label:中断所有的迭代,直接转到label的地方,不再进入迭代
int i=0;
        outer:
        while(true){
            System.out.println("Outer loop");
            while(true){
                i++;
                System.out.println("i="+i);
                if(i==3){
                    System.out.println("continue");
                    continue ;
                }
                if(i==5){
                    System.out.println("continue outer");
                    continue outer;
                }
                if(i==7){
                    System.out.println("break");
                    break ;
                }
                if(i==9){
                    System.out.println("break outer");
                    break outer;
                }

            }
        }
  • fibbo
static void fibbo(int n){
        int a=1,b=1,temp;
        if(n==1){
            System.out.println(a);
            return;
        }
        if(n==2){
            System.out.println(a);
            System.out.println(b);
            return;
        }
        System.out.println(a);
        System.out.println(b);
        for(int i=2;i<n;i++){

            temp = a+b;
            a = b;
            b = temp;
            System.out.println(b);
        }
    }
  • 吸血鬼数字,位数偶数;1260=21*60
    思路1:简单暴力方法
static void bloodNum(){
        int a,b,c,d;
        for(int i=1001;i<9999;i++){
            a = i/1000;
            b = (i/100)%10;
            c = (i/10)%10;
            d = (i%10);
            test(i,a,b,c,d);
            test(i,a,b,d,c);
            test(i,b,a,c,d);
            test(i,b,a,d,c);
            test(i,a,c,b,d);
            test(i,a,c,d,b);
            test(i,c,a,b,d);
            test(i,c,a,d,b);
            test(i,a,d,c,b);
            test(i,a,d,b,c);
            test(i,d,a,c,b);
            test(i,d,a,b,c);
        }
    }
    static void test(int i,int m,int n,int x,int y){
        if(i == (m*10+n)*(x*10+y)){
            System.out.println(i+"="+(m*10+n)+"*"+(x*10+y));
        }
    }

思路2:反过来计算,找符合的两位数

static void bloodNum(){
        for(int i=10;i<100;i++){
            for(int j=i;j<100;j++){
                int target = i*j;
                if(target<1000||target>9999){
                    continue;
                }
                int [] tar = {target/1000,target/100%10,target/10% 10,target%10};
                int [] get = {i/10,i%10,j/10,j%10};
                Arrays.sort(tar);
                Arrays.sort(get);
                if(Arrays.equals(tar,get)){
                    System.out.println(target);
                }

            }
        }
    }

第五章、初始化与清理

  • 5.1 用构造器确保初始化
    构造器采用与类相同的名字,初始化期间自动调用构造器。
    无参构造器(默认构造器):不接受任何参数

  • 5.2 方法重载
    相同名字的方法,参数不一样,每个都是独一无二的参数类型列表,(顺序不同也会区分)
    基本类型的重载:如果实际参数类型<小于方法中声明的形参类型,实际会被提升;char型略有不同,会被直接提升至int型。如果实际参数类型>方法中声明的形参类型,需要自己进行窄化转换。

  • 5.3默认构造器
    如果没有定义构造器,对象会自动生成一个无参构造器,并调用。

Dog d = new Dog();
        byte a=0;
        short b=0;
        d.bark();
        d.bark('c');
        d.bark(a);
        d.bark(b);
        d.bark(1);
        d.bark(1.0f);
        d.bark(1.0);

class Dog{

    void bark(){System.out.println("voidbark");}
    void bark(char c){System.out.println("char");}
    void bark(byte c){System.out.println("byte");}
    void bark(short c){System.out.println("short");}
    void bark(int c){System.out.println("int");}
    void bark(long c){System.out.println("long");}
    void bark(float c){System.out.println("float");}
    void bark(double c){System.out.println("double");}

}
  • 5.4 this关键字
    对于同一个类的两个对象,如何知道是那个调用了方法:
//编译器内部解决
Dog.function(引用,参数)

this:只能在方法内部使用,表示对“调用方法的那个对象”的引用

class Apple{
    void a(){
        System.out.println("functiona");
    }
    void b(){
        System.out.println("this-a");
        this.a();
        a();
    }
}

构造器中调用构造器

class flower{
    int count=0;
    String s = "initial";

    flower(int p){
        count = p;
        System.out.println("coun="+count);
    }
    flower(String ss){
        System.out.println("string="+s);
        s=ss;
    }
    flower(String s,int p){
        this(p);
        //this(s);  构造器只能调用一次
        this.s = s;
        System.out.println("String+int");
    }
    flower(){
        this("hi",7);
    }
    void pringfun(){
       // this(11);  其他方法不能调用构造器
        System.out.println("function pppppppp");
    }
}
  • static 含义:没有this的方法。可以不建立对象,通过类调用方法,static方法内不能用非静态方法。

  • 5.5 终结处理和垃圾回收
    finalize:
    对象可能不被垃圾回收
    垃圾回收不等于“析构”

Book a = new Book(true);
        a.checkIn();
        new Book(true).checkIn();
        System.gc();

class Book{
    boolean check = false;
    Book(boolean x){
        check = x;
    }
    void checkIn(){
        check = false;
    }

    @Override
    protected void finalize() throws Throwable {
        if(check){
            System.out.println("error:checkout");
        }
    }
}

Java GC:
GC Root(虚拟机中引用对象+方法区中的类静态属性+方法区中常量的引用对象+本地方法栈中引用对象)
从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活对象

  • 算法
    1、 停止赋值(stop and copy)(垃圾多的话效率高)——适合新生代GC
    2、 标记清扫(mark and sweep)(对于少量垃圾效率高,但是会产生过多碎片)
    3、 标记整理(Mark-compact)

新生代(Young):eden+survivor1+survivor2=8:1:1——Minor GC(复制算法)
老年代(Old):存放经过多次Minor GC存活下来的对象——Full GC(标记)
OOM(out of memory):当GC+非GC时间>GCTimeRatio 限制引发

  • 5.6成员初始化(Java中所有变量使用前都尽量初始化)
    方法中的局部变量如果没有初始化会报错;而类的数据成员会自动给初始值。

  • 5.7构造器初始化
    变量先初始化,初始化先静态对象,后非静态,静态对象只初始化一次,非静态对象每次都会调用。
    对象创建过程:查找类路径定位.class文件;载入文件进行初始化,只在对象首次加载时进行;new XX() 在堆上为对象分配空间;存储空间清零,所有对象自动成为默认值;执行初始化动作;执行构造器。

初始化的顺序

public class Chapter5 {
    public static void main(String[] args){
    System.out.println("inside main");
//        Cups.cup1.f(99);
    }
    static Cups cups1 = new Cups();
    static Cups cups2 = new Cups();
}


class Cup{
    Cup(int x){
        System.out.println("Cup("+x+")cup");
    }
    void f(int x){
        System.out.println("f("+x+")");
    }
}

class Cups{
    static Cup cup1;
    static Cup cup2;

    static {
        cup1 = new Cup(1);
        cup2 = new Cup(2);
    }
    Cups(){
        System.out.println("cups()");
    }
}

  • 5.8 数组初始化
    数组相等,只是针对引用的复制。
        int [] a1;
        int a[];

可变参数列表:

static void printArray(Object... args){
        for(Object x :args)
            System.out.println(x);

    }
static void pring(Object [] args){
        for(Object x :args)
            System.out.print(x+" ");
        System.out.println();
    }

    static void F(int require,String... orgs){
        for(String s:orgs){
            System.out.print(s);
        }
        System.out.println();
    }

printArray(47,3.14f,11.11);
        printArray(new Integer(34),new Float(3.13),new Double(11.11));
        printArray("one ","two","three");
        printArray(new Chapter5(),new Chapter5());
        pring(new Object[]{47,3.14f,11.11});

        F(3,"a","b","c");

重载的话,所有版本上都有可变参数列表,或者就不用

A(1,'b','a');
        A('a','b');//报错

static void A(float a,Character...args){
        System.out.println("first");
    }

    static void A(Character...args){
        System.out.println("second");
    }
  • 5.9 枚举类型
   Chapter5 a = new Chapter5(Money.E);
        Chapter5 b = new Chapter5(Money.Q);
        a.sw();
        b.sw();



    }
    Money degree;
    Chapter5(Money x){
        this.degree = x;
    }

    public void sw(){
        System.out.println("switch");
        switch (degree){
            case Q:System.out.println("Its q");break;
            case W:System.out.println("Its w");break;
            case E:System.out.println("Its e");break;
            case R:System.out.println("Its r");break;
            case T:System.out.println("Its t");break;
        }
    }

    public enum Sp{
        A,B,C,D
    }

    public enum Money{
        Q,W,E,R,T,Y
    }

第六章、访问权限控制

public_protected_(default)_private 权限由大至小

包内含有一组类,每个类只能含有一个public类

类内部同一package子类任何地方
private可以
default可以可以
protected可以可以可以
public可以可以可以可以

第七章、复用类(分文组合和继承的方法)

  • 1.组合(在新的类中产生现有类的对象)
public class Chapter7 {
    private Ano e;
    private String a,b;

    Chapter7(){
        a = "AAAAA";
        b = "BBBBB";
    }

    @Override
    public String toString() {
        if(e == null){
            e = new Ano();
        }
        return "A="+a+
                "B="+b+
                "e="+e;
    }

    public static void main(String[] args){
        Chapter7 x = new Chapter7();
        System.out.println(x);
    }
}
class Ano {
    private String s;
    Ano(){
        System.out.println("Ano construct");
        s = "IIIIIII";
    }

    @Override
    public String toString() {
        return s;
    }
}
  • 2.继承(按照现有类的类型来创建新类)
    每个类都可以有自己的main方法。
class Cleaner{
    private String s = "cleaner";
    public void append(String a){s+=a;}
    public void dilute(){append("dilute");}
    public void scrum(){append("scrum");}
    public void apply(){append("apply");}

    @Override
    public String toString() {
        return s;
    }

    public static void main(String[] args){
        Cleaner x = new Cleaner();
        x.apply();x.dilute();x.scrum();
        System.out.println(x);
    }
}

public class Chapter7 extends Cleaner{
@Override
    public void apply() {
        append("new apply");
        super.apply();

    }
    public void foam(){
        append("foam");
    }


    public static void main(String[] args){
        Chapter7 x = new Chapter7();
        x.apply();
        x.dilute();
        x.foam();
        System.out.println(x);

        Cleaner.main(args);
    }
  }

基类构造器总是会被调用,在导出类构造器调用前被调用。。
另外对于带参数的构造器,子类需要手动调用父类的构造器,因为自己写了带参数的构造器,就不会生成默认的不带参构造器。

  • 3.代理
    属于组合与继承之间的方法,直接在类中新建一个成员对象,然后调用成员对象的方法。

  • 4.结合使用组合和继承

名称的重载

class Chongzai{
    char fun(char c){
        System.out.println("Char fun");
        return c;
    }
    int fun(int c){
        System.out.println("Int fun");
        return c;
    }
    float fun(float c){
        System.out.println("Float fun");
        return c;
    }

}
class A extends Chongzai{
    String fun(String x){
        System.out.println("string a");

        return  x;
    }
    public static void main(String[] args){
        A x = new A();
        System.out.println(x.fun('a'));
        System.out.println(x.fun("abc"));

    }

}
  • 5、两者之间的关系
    组合是显示地做,适用于想在新类中使用现有类的功能,而非他的接口。即在新类中嵌入某个对象让其实现功能。然后再对于新类定义一些接口。

  • 6、protected 关键字(类的继承者可以访问,同一包内可以访问,对于其他的还是private)

  • 7 向上转型

class Amp{
    public void play(){System.out.println("play asd");}
    static void ht(Amp x){
        x.play();
    }
    void eat(){System.out.println("Amp eat");}
}

class Ampa extends Amp{

    public static void main(String[] args){
        Ampa x = new Ampa();
//        Amp.ht(x);
        Amp y = new Amp();
        x.play();
        x.grow(x);
        y.grow(x);//不能向下转型
        

    }
    static void grow(Amp x){
        System.out.println("Ampa grow");
        x.eat();
    }

    @Override
    public void play() {
        System.out.println("new play");
    }
}
8.Final关键字
  1. final数据 (final 以及 static final 的区别)
    如果修饰引用对象,引用对象的属性可以改变,而修饰基本类型才是不可改变
    static 说明只有一份,对于同一个类的不同对象,只会有这一个,final static 命名格式VAL_5
    final说明值是不可改变的,但是不同对象还是会生成不同的final值
class FinalData{
    private static Random rand = new Random(47);
    private String id;
    public FinalData(String s){this.id = s;}
    //对于static final变量命名需要大写

    private final int valueOne = 9;
    private static final int VALUE_TWO = 99;
    public static final int VALUE_THREE = 39;

    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(10);

    private Value v1 = new Value(22);
    private final Value v2 = new Value(11);
    private static final Value VAL_3 = new Value(33);

    //数组
    private final int[] a = {1,2,3,4,5};

    @Override
    public String toString() {
        return id+":"+"i4="+i4+",INT_5="+INT_5;
    }

    public static void main(String[] args){
        FinalData x = new FinalData("x");

        x.a[0]++;
        x.v2.i++;  //可以对引用类型的内部改变
        x.v1 = new Value(9);

//        x.VAL_3 = new Value(9); //final 类型
//        x.v2 = new Value(8);  //v2是final类型
//        x.a = new int[3]; //数组的引用是不可以改变的

        //对于变量随机赋值,不同的对象非静态的值不一样,但是静态的值只初始化一次,不会再改变了
        System.out.println(x);
        FinalData y = new FinalData("y");
        System.out.println(x);
        System.out.println(y);

    }

}

class Value{
    int i;
    public Value(int i){
        this.i = i;
    }
}

空白final:必须在构造器处初始化

class Pop{
    private  int i;
    Pop(int i){
        this.i = i;
    }
}
class BlankFinal{
    private final int a;
    private final Pop p;

    public BlankFinal(){
        a=1;
        p = new Pop(1);
    }
    public BlankFinal(int x){
        a=x;
        p = new Pop(x);
    }

    public static void main(String[] args){
        new BlankFinal();
        
    }
}

final参数:在方法内不可改变

  1. final方法: 把方法锁定,继承类就不可以修改了,等于private方法
  2. final类:不希望可以被继承,不需要改变。不过类中的变量可变,方法都相当于加了final
  • 初始化及类的加载:
    1.找到x.main(),找到x的编译代码(x.class文件下),注意到他还有个基类,对基类进行加载,不管是否调用对象这些都要加载。
    2.基类中的static初始化,然后是导出类的static
    3.最后是构造器进行。
class A{

    static int j =printInt("A.Initialized");
    static int printInt(String s){
        System.out.println(s);
        return 12;
    }
    A(){System.out.println("A construct");}
}
class B extends A{
    static int k = printInt("B.initialized");
    B(){System.out.println("B Construct");}
}
class C{
    static int j =printInt("C.Initialized");

    C(){System.out.println("c construct");}
    static A a =new A();
    static int printInt(String s){
        System.out.println(s);
        return 12;
    }
}

class H extends B{
    H(){System.out.println("H construct");}
    static int i = printInt("H initialized");
    public static void main(String[] args){

        System.out.println("start");

        H x = new H();
        System.out.println(C.a);

    }
}


///输出
A.Initialized
B.initialized
H initialized            所有的基类都会进行初始化
start
A construct
B Construct
H construct              新建对象,基类对象构造器先调用
C.Initialized
A construct
ThinkinJava.A@4554617c
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值