Java概念快速入门3

因此,通过覆盖,您可以使用相同的方法名称来引用不同实现的方法。 这是使用著名形状示例的示例。

 
class Shape { 
      public Shape() { 
       }
       public double getArea() {
             return 5.0;
       }
} 
class Circle extends Shape {
      double radius;
      public Circle(int radius) {
             this.radius = radius;
       }
      public double getArea() {
             return Math.PI * radius * radius;
      }
} 
class Rectangle extends Shape {
      int length;
       int width;
      public Rectangle(int length, int width) {
             this.length = length;
             this.width = width;
       } 
      public double getArea() {
              return length * width;
       }
}  
在这里,Rectangle和Circle类都从Shape扩展,并覆盖Shape类中无用的公共double getArea()方法,以提供每个类唯一的更有意义的实现。

覆盖方法的访问修饰符可以比覆盖方法允许更多但不能少于访问。 即,可以在子类中将超类中的受保护实例方法设为公共,但不能私有。 请记住,私有方法在子类中不可访问,因此不能被覆盖。 如果要覆盖某个方法但要使用您要覆盖的方法的超类版本计算的结果,则只需使用关键字super调用该超类方法,如下所示:


public double getArea() {
     return 5 + super.getArea();
} 
在这里,getArea()方法被覆盖,但是从直接超类计算得出的值被用于提出新版本的覆盖方法。

这几乎是覆盖的全部内容!

不要混淆重载和覆盖。 重载发生在名称相同但签名不同的同一类的方法之间,而重载发生在不同类的方法之间,其中一个是另一个的子类,并且方法必须具有相同的签名和返回类型或协变返回类型。

如果类A扩展了类B,则类型B的变量可以保存对类型A的对象的引用,反之则不能。 那是它的英文版本,它的java代码版本是:

 
class B{
}
class A extends B{
}
then 

B bVariable = new B(); //obviously allowed
B bVariable = new A(); //also allowed
A aVariable = new A();
A aVariable = new B();//! incompatible types.  
隐藏不是重载

当类中的静态方法具有与该类的超类相同的签名和返回类型时,就会发生隐藏。

 
class B{
     public static void test() {
            System.out.println("test from b");
     }
}
class A extends B{
       public static void test() {
              System.out.println("test from a");
       }
}
public class Test{
       public static void main(String[] args) {
             B b = new B();
             B a = new A();
             b.test();
            a.test();
      }
}  
版画
 test from b
test from b (this is not a typing error) 
方法test在B中是静态的,因此属于此类。

在main方法中,两个变量b和a共享相同的类B,因此在它们上调用类方法将调用同一方法。


A a = new A();
a.test(); 
将从a打印测试,因为现在类类型为A且在A内,因此B的测试方法现在被隐藏(未被A中的测试覆盖)。

实例方法的区别通过

 
class B{
     public static void test() {
           System.out.println("test from b");
     }
     void testInst() {
           System.out.println("testInst from b");
     }
}
class A extends B{
        public static void test() {
              System.out.println("test from a");
        }
        void testInst() {
             System.out.println("testInst from a");
        }
}
public class ShapeTest{
           public static void main(String[] args) {
                 B b = new B();
                 B a = new A();
                 b.test();
                 a.test();
                 b.testInst();
                 a.testInst();
        }
} 
使用:使用一句话,使用覆盖来实现从超类继承的方法的更特定实现。 抽象关键字

可以将一个类声明为抽象类,这意味着使用该类不能创建任何对象。

 abstract class A {
}
A a = new A();//!compile time error.
您可能开始认为抽象类是完全没有用的。 直到继承进入为止。您可以从抽象类继承,从而允许您创建可以实例化的类。 使类抽象的想法是,您有一个对象所属的通用组,但是实例化该通用组的对象确实没有任何意义,因为每个对象都属于一个更特定的组。 形状示例就是这种情况。 Shape类应该抽象化,因为可以仅通过将其称为形状来更精确地识别形状。 所以
abstract class Shape {
}
class Circle extends Shape {
} 
更有意义。

也可以将方法声明为抽象的,在这种情况下,您无需提供方法主体,而是将其留给继承子类。 在形状示例中,您知道

所有形状都有一个getArea方法,但不能为它编写任何代码,因为每种形状的实现都不同,因此请在shape类中声明getArea()方法

因为那是它的所属位置(所有形状都有一个getArea方法),但是由于您尚不知道如何编写,因此将其保留为抽象。

abstract class Shape {
public abstract double getArea();
} 
请注意,没有使用{}。 只是签名和; 在最后。

如果一个类包含一个抽象方法,则该类是隐式抽象,并且必须声明为抽象,否则编译器会抱怨。

如果一个类是从抽象类继承的,则该类必须提供超类中所有抽象方法的实现,否则,继承类也必须声明为abstract。

这些东西根本不是抽象的,您应该在编译器上尝试一下以查看效果。

介面

接口是一种引用类型,其成员可以是类,其他接口,常量和抽象方法。

它们与类的不同之处在于它们没有实现。 这是显而易见的,因为它们的所有方法都是抽象的。 因此,所有接口都是抽象的,但您不应该

放置公共修饰符。 所有接口成员都是隐式公共的。 基本上,接口是类可以选择签署的契约。 类通过使用Implements关键字实现接口来签署此合同。

这是两个示例界面

interface Shape {
double getArea();
}
interface Drawable {
void draw();
} 
这些接口每个都包含一种方法。 如果有任何类实现Shape接口,则它必须提供getArea()方法的实现,否则该类必须声明为抽象。

真的就是这么简单。 实施,否则您就是抽象的,那就是合同的规则。 界面是老板。 所有这些都在编译时检查。

接口也可以声明常量,这些常量可在实现类中使用。 一个类可以实现任意数量的接口。 您可以使用它通过实现多个接口来实现Java中某种程度的多重继承,从而能够将一个对象表征为多个组。 这是一个例子。 我们希望能够说一个圆形是一个Drawable对象,另一个圆形是一个Shape。

扩展Shape类表示圆形是一个形状。 扩展Drawable类可以说Circle是一个Drawable对象。 但是我们一次只能继承一个类,因此我们将其中一个作为接口,实现它并

扩展另一个,或者我们使它们都成为接口并实现它们。 决定权是我们自己决定的,但是接口实际上不提供任何代码重用,因为它们不包含任何实现,因此明智的是选择一种在代码重用方面允许我们达到最佳状态的方法。 接口提供的是多态性。 一个接口,多种实现。 例如,通过定义Drawable接口,我们可以在所有选择实现此接口的类中以不同方式实现它。 如果在某些类的绘制形状中有一个方法,我们只需要传递一个接口变量并调用其draw方法。

  
class Painter {
void drawShape(Drawable d) {
d.draw();
}
}  
现在,我们可以创建扩展Shape的类并实现Drawable。 在这些类中,由于我们已经实现了Drawable,因此我们提供了draw方法的自定义实现。 如果希望绘制任何形状,则将其传递给Painter的drawShape方法,该方法针对该特定形状调用draw方法。 当我们更改Circle类的draw方法时,Painter不会受到影响,其他任何形状也不会受到影响。 这是OOP的主要目标之一。 为了能够创建使系统部件更改的影响最小化的设计。 Java包中的类无可厚非地利用这些原理来定义可由程序员在各种情况下使用的类。

From: https://bytes.com/topic/java/insights/581237-quick-introduction-java-concepts-3-a

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值