🔎这里是JAVA成仙路,关注我学习JAVA不迷路
👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️
前言:本章具体介绍了抽象类和接口,整篇文章用目前流行的手机来举例,图解穿插代码案例。
JAVA成仙路从基础开始讲,后续会讲到JAVA高级,中间会穿插面试题和项目实战,希望能给大家带来帮助!
java语言,声明类时
abstractclass Db{} 说明Db类为抽象类。
java语言中,抽象方法是说没有方法的实现(方法体)此方法为抽象方法,只有抽象类和接口中才可以有抽象方法。
声明抽象类很简单,加个abstract关节字就行。
public abstract class AA {
}
在抽象类中声明一个抽象方法,抽象方法没有方法体,就是说现在这个方法就是个空架子。
public abstract class AA {
public abstract int a(int i);
}
描述:
小米手机生产厂生产手机,小米手机厂内部分为两个分厂,一个是红米手机厂,一个是黑米手机厂。
红米手机特点是屏幕大,充电快。
黑米手机特点是发热,音质好。
实现:
先声明一个抽象类 小米手机厂类,小米手机厂类里有两个抽象方法分别为a和b,还有一个定义过的方法c
再声明一个红米手机厂类继承小米手机厂,并且实现方法a和方法b
再声明一个黑米手机厂类继承小米手机厂,并且实现方法a和方法b
代码:
Mi.java
public abstract class Mi {
public abstract void a();
public abstract void b();
public void c(){
System.out.println("小米手机好");
}
}
Hong.java
public class Hong extends Mi {
@Override
public void a() {
System.out.println("红米手机屏幕大");
}
@Override
public void b() {
System.out.println("红米手机充电快");
}
}
Hei.java
public class Hei extends Mi {
@Override
public void a() {
System.out.println("黑米手机发热");
}
@Override
public void b() {
System.out.println("黑米手机音质好");
}
}
测试:
public class Test {
public static void main(String[] args) {
Hong hong = new Hong();
Hei hei = new Hei();
hong.a();
hong.b();
hong.c();
hei.a();
hei.b();
hei.c();
}
}

这个案例的主要描述了抽象方法的一个应用场景,红米和黑米是小米的一个分支,他们有小米的部分功能,但是他们还想有自己的特色。那么就可以通过实现小米的两个抽象方法来实现自己的特色。并且小米只声明了两个抽象方法,限制了两个子厂的特色,让他们只能增加两个特色,不能无限制的随意增加多个特色。
使用规则
- 抽象类必须被继承,抽象方法必须被重写。
- 抽象类中的抽象方法只需声明,无需实现,没有方法体
- 抽象类不能被实例化,抽象类不一定要包含抽象方法,而定义抽象方法的类必须是抽象类。
- 抽象类包含的抽象方法必须在其子类中被实现,否则该子类也必须是抽象类。
- 抽象类可以有构造方法供子类实例化对象
- 抽象类不能直接实例化使用,一般用的是抽象类的子类,
A a = new B();
A和B之间的关系,继承关系,接口实例关系。
类:方法+属性+静态程序段+初始化程序段
抽象类:方法+抽象方法+属性+静态程序段+初始化程序段
抽象类本质
1.从类的组成上看其是抽象方法和非抽象方法的集合,还有属性(常量)。
2.从设计的角度来看,实际上抽象类定义了一套规范(抽象方法)。(规范)
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
interface关键字声明接口AA
public interface AA {
}
描述:
富士康加工厂里有两个分厂,分别是加工华为手机和苹果手机。每个手机是由电池、芯片、屏幕这三个硬件组成。两个品牌的手机都是由这三个硬件组成但是硬件的型号不同。
但是这两个厂都有一个统一的加工程序把手机组装
实现:
声明富士康接口,接口内声明一个抽象方法用来组装手机。
华为和苹果两个类分别实现富士康接口,并且实现里面的方法。
富士康接口
public interface Fu {
void zhuang();
}
华为加工厂
public class HuaWei implements Fu {
private final String xin = "麒麟芯片";
private final String dian = "6000am电池";
private final String ping = "大猩猩屏幕";
@Override
public void zhuang() {
System.out.printf("华为手机:%s,%s,%s %n", xin, dian, ping);
}
}
苹果加工厂
public class Iphoe implements Fu {
private final String xin = "A15芯片";
private final String dian = "3000am电池";
private final String ping = "小猩猩屏幕";
@Override
public void zhuang() {
System.out.printf("苹果手机:%s,%s,%s %n", xin, dian, ping);
}
}
测试
public class Test {
public static void main(String[] args) {
HuaWei huaWei = new HuaWei();
Iphoe iphoe = new Iphoe();
huaWei.zhuang();
iphoe.zhuang();
}
}

接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。