【有书共读】《疯狂JAVA讲义》读书笔记06

《疯狂Java讲义》第六周笔记06
阅读了java疯狂讲义第六章的内容,我对面向对象思想有了更深入的了解,对java中的修饰符类似于static、final等有了一定的了解,还知道了接口的概念与作用,通过对这章的学习学到了很多东西。

理解类成员

类成员就是用static修饰的成员变量,方法,初始化块,内部类的统称。能通过对象访问这些类成员。即使对象是null 。类成员不能访问实例成员,因为类成员的作用域更大,可能类成员还存在,但是成员变量已经不存在了,所以不能够访问实例成员。

单例类

一个类始终只能创建一个实例,称为单例类。
如果不想让别的类轻易的创建该类的对象,就需要把类的构造函数设置成private,但是这个时候就需要有一个方法来创建一个对象,由于使用这个方法的时候还没有对象,因此需要给方法是static的。
同时。为了满足只能创建一个对象,则必须把已经创建的对象保存起来,每次创建对象之前都检查一下是否只有一个对象。由于存储对象的成员变量需要通过上面的static方法调用,因此需要设置为static。

	

package demo6;

public class Singleton {

    //定义一个类变量用来保存创建出来的对象

    private static Singleton instance;

    private Singleton(){}

    //定义一个能够返回对象的方法

    public static Singleton getSingleton()

    {

        if(instance==null)

        {

            instance=new Singleton();

        }

        return instance;

    }

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        Singleton s1=Singleton.getSingleton();

        Singleton s2=Singleton.getSingleton();

        System.out.print(s1==s2);

 

    }

 

}

final修饰符

final修饰变量时候表示该变量一旦获得了初始值,就无法再改变。

 final成员变量

类变量:在静态初始化块或者声明该变量时初始化
实例变量:在普通初始化块,或者声明该变量时候,或者构造器。如果已经在普通初始化块赋值,则不可以再在构造器中赋值。
注意⚠:普通方法不能访问final修饰的成员变量。
final修饰的成员变量必须程序员自己显示初始化,系统不会默认赋值。

final局部变量

因为系统不会给局部变量初始化,因此在用final修饰的局部变量不一定非由程序员显示初始化。
方法中的形参不能够在方法里面初始化,因为形参的初始化是在被调用的时候由实参传入的。

final修饰基本类型变量和引用类型变量的区别

final修饰基本类型变量,就不能更改值了。如果是引用类型,则只要不改变地址就行,里面的内容可以随意

	

package demo6;

import java.util.Arrays;

class Person1{

    private int age;

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public Person1() {}

    public Person1(int age)

    {

        this.age=age;

    }

}

 

public class FinalReferenceTest {

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        //可以无限的更改数组里面的内容,但是不能够更改数组的地址

        final int[] iArr={3,4,5,6};

        iArr[2]=19;

        System.out.print(Arrays.toString(iArr));

        Arrays.sort(iArr);

        System.out.println(Arrays.toString(iArr));

        //iArr=null;

        Person1 p1=new Person1();

        p1.setAge(7);

        //这里竟然可以更改,,,,,不懂不懂

        p1=null;

        System.out.print(iArr);

        

 

    }

 

}

可执行“宏替换”的final变量

变量满足三个条件,则变量相当于一个直接量

1. final修饰

2. 在定义的时候指定了初始值(只有在定义的时候赋值才有这种效果)

3. 值可以在编译的时候确定下来

final 方法

final方法不能够被重写。如果父类的方法不希望子类重写,只要加上final 就好。
但是父类的private 是不会被子类继承的,因此也不会有重写这个说法。因此如果父类的private方法被final了,子类仍然可以写一个一样的方法。

final类

不能有子类的类

不可变类

不可变类是创建该类的实例后,实例变量不能够更改。
创建自定义的不可变类方法:
1,类的成员变量用private和final修饰
2,提供带参数的构造函数,用于根据传入参数来初始化类的成员变量
3,该类仅有getter
4,重新定义equals()和hashcode()

	

package demo6;

public class Address {

    private final String detail;

    private final String postCode;

    public Address()

    {

        this.detail="";

        this.postCode="";

    }

    public Address(String detail,String postCode)

    {

        this.detail=detail;

        this.postCode=postCode;

    }

    public String getDetail()

    {

        return detail;

    }

    public String getPostCode()

    {

        return postCode;

    }

    public boolean equals(Object obj)

    {

        if(obj==this)

        {

            return true;

        }

        if(obj!=null&&obj.getClass().equals(Address.class))

        {

            Address AddObj=(Address)obj;

            if(AddObj.getDetail().equals(this.getDetail()))

            {

                return true;

            }

        }

        return false;

    }

    

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        

 

    }

 

}

当创建不可变类的时候,如果成员变量里面有引用类型,则很可能创建出一个可变类,因为成员变量的内容可以更改。必须采用一些其他的方法,才能创建真正的不可变类。

缓存实例的不可变类

缓存实例的不可变类,是因为有的时候一个对象的某个成员被多次引用,为了节省开销,可以把它缓存起来。下边是把它缓存在数组里面,如果缓存里面已经有了,就直接返回实例,如果没有,就新建实例加进去。

	

package demo6;//这个类主要是弄一个数组,然后缓存string数据class CacheInnutale{

    private static int MAX_SIZE;

    private static CacheInnutale[] ***=new CacheInnutale[MAX_SIZE];

    //pos为什么要是static

    private static int pos=0;

    private final String name;

    public String getName() {

        return name;

    }

    private CacheInnutale(String name)

    {

        this.name=name;

    }

    // 使用数组缓存已有的实例,并且记录缓存的位置

    public static CacheInnutale valueOf(String name)

    {

        //遍历已经缓存的对象,如果有相同的,直接返回缓存的实例

        for(int i=0;i<name.length();i++)

        {

            if(name!=null&&***[i].getName().equals(name))

            {

                return ***[i];

            }

        }

        //如果缓存已经满了,则从头开始缓存

        if(MAX_SIZE==pos)

        {

            ***[0]=new CacheInnutale(name);

            pos=1;

        }

        //缓存没满的话,把新建的对象缓存起来

        else 

        {

            ***[pos++]=new CacheInnutale(name);

        }

        //因为是后➕,所以pos-1

        return ***[pos-1];

    }

}

public class CacheInnutaleTest {

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

 

    }

 

}

抽象类

抽象方法是只有方法的签名,没有方法的实现

抽象方法和抽象类

抽象方法和抽象类必须使用abstract修饰,有抽象方法的类一定是抽象类。
规则:

1. 抽象方法不能有方法体

2. 抽象类不能够被实例化

3. 抽象类的构造函数不能够用来创造实例,主要用于被子类调用

4. 含有抽象方法的类(包括直接定义了一个抽象方法;继承了一个抽象父类,但是没有完全实例化父类包含的抽象类;或是实现了一个接口,但是没有完全实例化接口包含的抽象方法)

	

public class Triangle extends Shape{

    //定义三角形的三边

    private double a;

    private double b;

    private double c;

    public Triangle(String color,double a,double b,double c)

    {

        super(color);

        this.sideSides(a,b,c);

    }

    public void sideSides(double a,double b,double c)

    {

        if(a+b<=c||a+c<=b||c+b<=a)

        {

            System.out.print("两边之和必须大于第三边");

            return ;

        }

        this.a=a;

        this.b=b;

        this.c=c;

        

    }

    //重写计算周长的方法

    public double calPerimeter()

    {

        return a+b+c;

    }

    public String getType()

    {

        return "三角形";

    }

    public static void main (String[] args)

    {

        //如果不用抽象类的话,s1是不能够直接调用gettype方法的。

         

        Shape s1=new Triangle("yello", 3, 4,5);

        System.out.println(s1.getType());

        System.out.print(s1.calPerimeter());

    }

}

abstract与final不能同时出现:abstract类表示只能被继承,但是final类不能被继承。 abstract和static一般不能同时修饰方法:static修饰的方法表示属于类的,可以通过类来访问。但是如果同时也是abstract的话,则没有方法体。这就没办法调用。(内部类除外) abstract和private不能同时修饰方法:private修饰的方法是不会被继承的。但是abstract需要继承。

抽象类的作用

作为子类的模版。

java8改进的接口

将抽象类“抽象”到极致,只包含抽象方法。就是接口。

接口的概念

接口定义的是多个类共同的公共行为规范,接口里通常是定义一组公共方法。
接口不提供任何实现,体现的是实现和规范相分离的设计哲学。

java8中接口的定义

关键词:interface
修饰符:public 或者省略,省略是默认default
一个接口可以继承多个接口

由于接口定义的是一种规范,因此接口没有构造器和初始化块,接口可以包含成员变量(静态常量),静态方法和抽象方法以及默认方法。都必须是public

1. 静态常量:无论是否有修饰符,都是public static final的,需要在定义的时候指定默认值。可以跨包访问,但是因为是final,不能修改值。

2. 接口里面的普通方法只能是public的抽象abstract方法

3. 在接口定义默认方法,需要使用default修饰(默认都是public修饰,不能static修饰)

4. 在接口定义类方法,需要使用static(默认都是public ,不能用default修饰)

5. java里面最多定义一个public的接口,如果有public的接口,则主文件名和接口名相同

接口的继承

支持多继承,以逗号分格

使用接口

implements实现多个接口。如果一个类继承了一个接口,就必须把里面的抽象方法都实现,否则就必须定义成抽象类。
实现接口的方法时必须使用public
模拟多继承:接口名引用变量名=new 类(初始化参数),类就可以访问接口的方法以及自己的方法。类的方法就变的很多。

	

package demo6;//定义一个product接口interface Product{

    int getProductTime();

}public class Printer implements Product , Output{

    private String[] printData=new String[MAX_CACHE_LINE];

    //记录当前需打印的作业数

    private int dataNum=0;

    public void out()

    {

        //只要还有作业就继续打印

        while(dataNum>0)

        {

            System.out.println(printData[0]);

            System.arraycopy(printData, 1, printData, 0, --dataNum);

        }

    }

    public void getData(String msg)

    {

        if(dataNum>=MAX_CACHE_LINE)

        {

            System.out.println("输出队列已经满了。添加失败");

        }else {

            printData[dataNum++]=msg;

        }

    }

    public int getProductTime()

    {

        return 45;

    }

    

    

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        //创建一个printer对象,当成output使用

        Output o=new Printer();

        o.getData("疯狂jav");

        o.getData("疯狂jaba讲义");

        o.out();

        o.getData("疯狂安卓讲义");

        o.getData("疯狂安卓");

        o.out();

    }


}

接口和抽象类

接口:体现一种规范,对于接口的实现者,接口定义了必须实现那些服务;对于接口的调用者,规定了调用者可以调用哪些方法。
抽象类:体现一种模版的设计,他是没有设计完的一个类,需要子类补充将它完成。

#笔记##读书笔记#
全部评论

相关推荐

亮点儿:昨天二面,今天看状态回到一面了查看图片
点赞 评论 收藏
分享
05-23 20:31
已编辑
武汉大学 Java
内向的柠檬精在研究求职打法:注意把武大标粗标大 本地你俩不是乱杀
点赞 评论 收藏
分享
只有一个苍穹外卖外加正在看黑马点评,可以找小厂实习吗,还有我的简历有什么大问题吗
Java抽象小篮子:感觉有点熟悉,问题1是学历,2是没实习经历,3是专业技能写得太少太少了(怎么写可以看我置顶帖),4是仅这一个项目找实习不够看。拷打完毕,简历怎么写可以看我置顶帖子
点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务