How Groovy, Scala, and Clojure incorporate behavior into a class

Source: Internet
Author: User
Tags class definition contains expression extend inheritance integer grails multiple inheritance in c

The design of the Java language has been purposefully cut to avoid some problems that have been discovered in the previous generation of products. For example, the designers of the Java language feel that multiple inheritance in C + + poses too much complexity, so they choose not to include the attribute. In fact, they rarely build extensibility options in the language, relying only on single inheritance and interfaces.

Other languages, including the Java Next generation language, have great potential for expansion. In this and the next two installment, I'll explore ways to extend Java classes without involving inheritance. In this article, you'll learn how to add a method to an existing class, either directly or through the syntax sugar (syntactic sugar).

Problem with an expression

The problem of expression is a well-known observation in recent history of computer science, pioneered in an unpublished paper by Philip Wadler of Bell Labs. (Stuart Sierra explained it brilliantly in its DeveloperWorks article, "Through the Clojure 1.2 solution expression problem." In this article, Wadler said:

The expression problem is the new name for the old problem. Our goal is to define data types through a case where you can add new cases to new functions of data types and data types without recompiling existing code, while preserving static type safety (for example, no conversions).

In other words, how do you add functionality to a class in a hierarchy without resorting to type conversions or if statements?

We will use a simple example to illustrate the expressive form of the problem of expression in the real world. Suppose your company always assumes that the length unit in your application is m and does not build any functionality in your class for any other length unit. But one day, your company merged with a competitor, and the competitor always assumed that the unit of length was feet.

One way to solve this problem is to extend the Integer by using a transformation method to make switching between the two formats irrelevant. Modern languages offer a variety of solutions for this purpose; In this installment, I will focus on 3 of them:

Open Class

Wrapper class

Agreement

Groovy Categories and Expandometaclass

Groovy contains two different ways to extend an existing class using open classes, and "reopen" a class definition to implement the ability to change, such as adding, changing, or deleting methods.

Category class

Class classes (a concept that borrows from OBJECTIVE-C) are general classes that contain static methods. Each method takes at least one parameter that represents the type of method expansion. If you want to add a method to the Integer, for example, I need to accept the type as the first parameter of the static method, as shown in Listing 1:

Listing 1. Groovy's category Class

Class Integerconv {
  static double getasmeters (Integer self) {
    self * 0.30480
  }
    
  static Double Getasfeet ( Integer self) {
    self * 3.2808
  }
}

The Integerconv class in Listing 1 contains two curried methods, each of which accepts an Integer parameter named self (a generic idiomatic name). To use these methods, I must wrap the reference code in a block of usage code, as shown in Listing 2:

Listing 2. Use category Class

@Test void Test_conversion_with_category () {use
  (integerconv) {
    assertequals (1 * 3.2808, 1.asFeet, 0.1)
    Assertequals (1 * 0.30480, 1.asMeters, 0.1)
  }
}

In Listing 2, there are two places that are particularly interesting. First, although the extension method in Listing 1 is named Getasmeters (), I call it 1.asMeters. Groovy syntax sugar around the properties in Java enables me to execute the Getasmeters () method as if it were a field of a class named Asmeters. If I omit as in the extension method, the call to the extension method needs to use an empty parenthesis, just like in 1.asMeters (). Generally speaking, I prefer cleaner property syntax, which is a common technique for writing domain-specific languages (DSLs).

The second place to note in Listing 2 is a call to Asfeet and asmeters. In the use code block, I call the new method and the built-in method equally. This extension is transparent within the lexical scope of the use code block, which is good because it limits the scope of the extended (sometimes core) classes.

Expandometaclass

Categories are the first extension mechanism that Groovy adds. But it turns out that groovy's lexical scope is too restrictive for building Grails (the Groovy Web framework). As a result of the limitations in the dissatisfaction category, one of Grails's creators, Graeme Rocher, added another extension mechanism to Groovy: Expandometaclass.

Expandometaclass is an extended holder of lazy instantiation that can be "grown" from any class. Listing 3 shows how to use Expandometaclass to implement my extensions for my Integer class:

Listing 3. Using Expandometaclass to extend the Integer

Class integerconvtest{
    
  static {
    Integer.metaClass.getAsM {->
      delegate * 0.30480
    }
    
    Integer.metaClass.getAsFt {->
      delegate * 3.2808
    }
  }
    
  @Test void Conversion_with_expando () {
    Asserttrue 1.asM = = 0.30480
    asserttrue 1.asFt = = 3.2808
  }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.