Java接口与抽象(学习笔记)
来源:互联网 发布:excel重复数据高亮 编辑:程序博客网 时间:2024/06/05 00:56
一、== 和 equals方法
当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就返回true。
但对于两个引用类型变量,只有他们指向同一个对象时,==判断才会返回true。==不可以用来比较两个类型上没有父子关系的对象。
public class EqualTest
{
publicstatic void main(String args[]){
inti = 65;
floatf = 65.0f;
charc = 'A';
System.out.println("65和 65.0f 的比较结果 " + (i == f));
System.out.println("65和 'A' 的比较结果 " + (i == c));
System.out.println("65.0f和 'A' 的比较结果 " + (f == c));
Stringstr1 = new String("hello");
Stringstr2 = new String("hello");
System.out.println("str1== str2 ? " + (str1 == str2));
System.out.println("str1equals str2 ? " + str1.equals(str2));
//下面的语句在编译时发生错误
//System.out.println("hello"== new EqualTest());
Strings1 = "疯狂Java";
Strings2 = "疯狂";
Strings3 = "Java";
Strings4 = "疯狂" + "Java";
Strings5 = "疯"+"狂"+"Java";
Strings6 = s2 + s3;
Strings7 = new String("疯狂Java");
System.out.println("\n\n"+ (s1==s4));
System.out.println(s1==s5);
System.out.println(s1==s6);
System.out.println(s1==s7);
}
}
String还有一个非常容易迷惑的地方:
‘’hello”直接量和new String(“hello”);有什么区别呢?当直接使用形如”hello”的字符串直接量时,JVM将会使用常量池来管理这些字符串;当使用new String(“hello”);时,JVM将会先使用常量池来管理”hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象将会被保存在堆内存中。换句话说,new String()一共产生了两个字符串对象。
二、单例类
见如下代码:
class Singleton
{
//instance用来缓存曾经创建的实例对象。由于需要被get方法访问,所以需要static修饰符
privatestatic Singleton instance;
//使用private修饰,为了隐藏该构造器,不致以被其他类访问,从而创建多个对象
privateSingleton(){}
//(与外部的接口)调用该方法创建实例对象,因此用public修饰,但调用该方法时还没有对象,只能通过类调用,将该方法声明为类方法,因此用static修饰
publicstatic Singleton getInstance(){
if(instance== null){instance = new Singleton();}
returninstance;
}
}
public class SingletonTest
{
publicstatic void main(String args[]){
Singletons1 = Singleton.getInstance();
Singletons2 = Singleton.getInstance();
System.out.println(s1==s2);
}
}
小提示:类变量和实例变量有什么区别?类变量是所有实例共同拥有,只要一个改变,则所有对象的该变量都随着改变,类变量由static关键字声明,系统为每个类变量分配一次存储空间。实例变量是类实例化后,系统为其创建的一个类的实例变量拷贝,每个实例拥有一个实例变量,实例变量是对象私有的,某一对象将其改变,不影响其他对象。
三、final修饰符
当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用一个对象,但这个对象的内容完全可以发生改变。例如:
Final int[] iArr = {1,2,3,4,5};
iArr[2] = 100; //这是合法的
iArr = null;//这是非法的
对于实例变量也如此。
Final修饰的方法不能被重写,final修饰的类没有子类。
四、抽象类
抽象方法和抽象类必须使用abstract修饰符来定义。有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。抽象方法是指只有方法名,没有方法实现的方法。
抽象类不能被实例化,但抽象类里可以包含构造器,这儿的构造器并不是实例化时使用,而是提供给该抽象类的子类使用。
Private和abstract不能同时修饰方法(因为abstract修饰的方法必须被重写才有意义,private修饰的方法不能被继承,即不能被重写)。
Final和abstract永远不能同时使用(因为final类不能被继承,而abstract修饰的类必须被继承重写才有意义)。但内部类除外。
抽象类的作用:从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。
public abstract class Shape
{
{System.out.println("执行Shape的初始化块");}
privateString color;
publicabstract double getPerimeter();
publicabstract String getType();
publicShape(){}
publicShape(String color)
{
System.out.println("执行Shape的构造器");
this.color= color;
}
publicvoid setColor(String color)
{
this.color= color;
}
publicString getColor()
{
returnthis.color;
}
}
public class Triangle extends Shape
{
privatedouble a;
privatedouble b;
privatedouble c;
publicTriangle(String color, double a, double b, double c)
{
super(color);
this.setSides(a,b,c);
}
publicvoid setSides(double a, double b, double c)
{
if(a>= b+c || b >= a+c || c >= a+b)
{
System.out.println("三角形两边之和大于第三 边");
return;
}
this.a= a;
this.b= b;
this.c= c;
}
publicdouble getPerimeter()
{
returna+b+c;
}
publicString getType()
{
returngetColor() + "三角形";
}
}
public class Circle extends Shape
{
privatedouble radius;
publicCircle(String color, double radius)
{
super(color);
this.radius= radius;
}
publicdouble getPerimeter()
{
returnMath.PI*radius*2;
}
publicString getType()
{
returngetColor() + "圆形";
}
}
public class ShapeTest
{
publicstatic void main(String args[])
{
Shapet = new Triangle("白色",3,4,5);
Shapec = new Circle("红色", 3);
System.out.println(t.getType());
System.out.println(t.getPerimeter());
System.out.println(c.getType());
System.out.println(c.getPerimeter());
}
}
另一个例子:
public abstract class SpeedMeter
{
privatedouble trunRate;
publicabstract double getRadius();
publicvoid setTrunRate(double trunRate)
{
this.trunRate= trunRate;
}
publicdouble getSpeed()
{
return2 * Math.PI * getRadius() * trunRate;
}
}
public class CarSpeedMeter extendsSpeedMeter
{
publicdouble getRadius()
{
return0.28;
}
publicstatic void main(String args[])
{
CarSpeedMetercar = new CarSpeedMeter();
car.setTrunRate(15);
System.out.println(car.getSpeed());
}
}
五、接口
由于接口定义的是一种规范,因此接口里不能包含构造器和初始化块定义。接口里可以包含成员变量(只能是静态常亮)、方法(只能是抽象方法、类方法、默认方法)、内部类。接口里的所有成员都是public访问权限。
在接口中定义成员变量时,不管是否使用public static final来修饰,接口里的成员变量总是使用这三个修饰符(即int MAX = 50; 和 public static final int MAX = 50 ;的写法完全一样)。接口里定义的成员变量只能在定义时指定默认值。
Java8允许在接口中定义类方法和默认方法(有方法体),访问权限都是public。类方法必须用static修饰,默认方法必须用default修饰。由于默认方法没有static修饰,所以不能直接使用接口来调用,需要使用接口的实现类的实例来调用。而类方法可以直接使用接口调用。
六、抽象与接口
接口体现的是一种规范,一种标准。类似于整个系统的“总纲”,制定了系统各个模块应该遵循的标准,一旦接口改变,对整系统的影响是辐射式的。
抽象体现的是一种模板设计模式。抽象类可以被当成系统实现过程中的中间产品,这个中间产品已经实现了系统的部分功能,但这个产品依然不能当成最终产品。
相同点:
① 接口和抽象类都不能被实例化,他们都位于继承树的顶端,用于被其他类实现或继承;
② 接口和抽象类都可以包含抽象方法,实现接口或者继承抽象类的普通子类都必须实现这些抽象方法。
- Java接口与抽象(学习笔记)
- Java接口与抽象类学习笔记
- java学习笔记----抽象类与接口
- JAVA学习笔记(六)抽象类与接口
- java学习笔记(十六)抽象类与接口
- 《JAVA与模式》学习笔记之接口与抽象类
- java学习---抽象与接口
- java学习笔记-抽象类abstract与接口interface
- 01-java学习笔记【接口与抽象类】
- 【Java学习笔记】3:抽象类与接口
- Java学习笔记 --抽象类与接口 基于类Shape
- 抽象类与接口学习笔记
- 抽象类与接口学习笔记
- 【JAVASE_学习笔记】抽象类与接口
- java学习笔记(类、抽象类和接口)
- Java之学习笔记(22)------------抽象类和接口
- JAVA学习笔记(抽象类和接口)
- Java学习笔记(一)----封装 继承 多态 抽象 接口
- [BZOJ2908] 又是nand (树链刨分)
- 关于Fedora下无法访问Windows的NTFS文件系统
- 杂谈之Windows共享文件机制的实现方法
- 谁将引领未来高清音频!杜比TrueHD对比DTS-HD
- Spring Bean装配:Bean注解实现以及定义
- Java接口与抽象(学习笔记)
- API接口非幂等性问题及使用redis实现简单的分布式锁
- mybatis--map映射文件 标签详解
- 【算法】错排——错误引发的讨论
- 搭建云服务器--移动应用开发
- 从堆栈快速定位出错的代码行
- uvalive 4992 半平面交
- 关联规则挖掘算法Aprior和FPGrowth对比与改进
- NAT工作原理