JAVA 8学习笔记-第四章

CHAPTER 4 Methods and Encapsulation

1. Designing Methods

public final void nap(int minutes) throws InterruptedException {  //body}

access modifier: public, optional

optional specifier: final, optional

return type: void, required

method name: nap, required

parameter list: (int minutes), required, but can be empty ()

Optional exception list: throws InterruptedException, optional

method body: {}, required, can be empty{}

 

1) Access Modifier

private: can be called ONLY within the same class

default: can be called within the same class or by the classes within the same package, simply omitted

protected: can be called within the same class or by the classes within the same package or subclasses

public: can be called by any class

examle:

default void walk2(){}  //compile error, default is not a access modifier

void public walk3(){}  //compile error, return type can't be put before the access modifier

 

2) Optional Specifier

can have multiple optional specifier, can be put in any order

static: used for class method

final: used when a method is not allowed to be overridden by a subclass

abstract: used when not providing a method body

example:
public void final walk6(){}  // compile error, optional specifier cann't be put after return type

final pulic void walk7(){}  // compile OK, optional specifier can be put before the access modifier

 

3) Return Type

method must have a return type, when no value is returned , void is being used.

void: can have a return statement without value, or omit the return statement

other return types: must have a return statement with a primitive or object that matches the return type.

example:

void walk1(){}

void walk2(){return;}

int num(){return 2L;}  // compile error, NOT assignable to the return type

 

4) Method Name

name rules as same as variable name's

- only contain letters, numbers, _ or $

- can NOT begin with numbers

- can NOT use reserved words like class, void, int, break....

 

5) Parameter List

- can be empty()

- multiple parameters separated by comma

 

6) Optional Exception List

-  list many types of exceptions separated by comma

 

7) Method Body

code block which contains zero or more statements

 

8) Varargs

vararg parameter must be the last element in the method's parameter list.

when calling a method with a vararg parameter, you have two choices

- pass in a array, two ways: new int[2] or new int[] {2,3}

- list the elements of the array, and let JAVA create it for you

accessing the numbers of vararg just like accessing an array

example:

public static void walk(int num, int... nums){}

walk(1);  // JAVA creates an array of length 0

walk(1,2);  //JAVA creates an array of length 1

walk(1,2,3);  //JAVA creates an array of length 2

walk(1, new int[] {4,5});   // pass in a array of length 2

walk(1, {4, 5});  // compile error, wrong way to create an array

walk(1, null);  // JAVA treats null as reference of array

int num = nums[0];  // access number of vararg

 

9) Applying Access Modifier

- private 

- default

- protected: protected member can be used without referring a variable within classes in the same package or subclasses, or by referring a variable which is a reference to the class in the same package or the SAME subclass where the reference appears.

- public 

example:

package pond.shore;

public class Bird{

  protected String text = "floating";  // protected access

  protected void floatWater(){    // protected access

    System.out.println(text):
  }

}

 

package pond.swan;

import pond.shore.Bird;  //different package

public class Swan extends Bird{  //create subclass

  public void swim(){

    floatWater();  // call protected member without referring a variable

    System.out.println(text);  // call protected member

  }

  public void helpOtherSwanSwim(){

    Swan other  = new Swan();

    other.floatWater();   // call protected member through a variable referring to the same class Swan

    System.out.println(other.text);  

  }

  public void helpOtherBirdSwim(){

    Bird other  = new Bird();  // NOT refer to Swan

    other.floatWater();  // does not compile,  cause Bird is in a different package ( imported class Birdand compared to pond.shore.Bird ) and it doesn't inherit from Bird.

    System.out.println(other.text);  // not compile

  }

  public void helpOtherSwanFly(){

    Bird other = new Swan();

    other.floatWater();  // does not compile, cause object Swan is stored in Bird reference.

    System.out.println(other.text);  // not compile
  }
}

 

package pond.goose;

import pond.swan.Swan;

public class Goose extends Swan{  //subclass of subclass of Bird

  public void helpGooseFly(){

    Swan swan = new Swan();  //NOT refer to Goose 

    swan.floatWater();   // not compile, reason same to Bird in the last example

    System.out.println(swan.text);  // not compile

  }

  public void helpGooseSwim(){

    Goose goose = new Goose();

    goose.floatWater();  // compile OK

    System.out.println(goose.text);   // compile OK

  }
}

 

10) Static Methods and Fields

Static methods don't require an instance of the class, they are shared among all users of the class.

instance --- instance member, only data gets space in the stack, only one code copy. Only run when initialized, means never run if not initialized

class --- static member, only data gets space in the stack, only one code copy. Only run one time when the class is used. can be modified by instance member.

- a static member can NOT call an instance member (variable or method) directly, but can call it as an object member, like new Test().text

- a static member can call a static member by using classname

- an instance member can call an instance member by using reference variable (omit it when one method calling another in the same class)

- an instance member can call a static member by using the classname or reference variable 

example:

class Order {    // if there is public access modifier, this class should be saved in a separate file named Order.java.

  static String result = "";

  { result += "c"; }  // instance initializer

  static

  { result += "u"; }  // static initializer although it is at different line with keyword "static"

  { result += "r"; }  // instance initializer

}

public class OrderDriver {

  public static void main(String[] args) {

    System.out.print(Order.result + " ");  //static initializer is only run once

    System.out.print(Order.result + " ");

    new Order();  // trigger the instance initializer which can change the value of static member

    new Order();  // trigger the instance initializer which can change the value of static member

    System.out.print(Order.result + " ");

}}  // result is "u u ucrcr"

  

static final --- constant, using all upper letters with underscore between words as name. NOT allowed to resign to another object

static initializer -- static{}, the only place where the static variables could possibly get initialized.

instance initializer -- {}

example:

private static int num1;  //compile error, no initialization in the declaration line and static initializer

private static int num2;

static{ num2 =3; }

- try to avoid using static or instance initializer, cause it makes the code hard to read

- all the instance initialization can be done inside the constructor

- to use the static initializer to initialize static fields requiring more than one line of code. 

static import are only used for importing static members, not the whole class.

regular imports are used for importing classes.

parameters has no business with static import.

example: import error

import static java.util.Collections.sort(ArrayList<String>);  // compile error, parameters are not needed.

import static java.util.Collections.sort;  // correct

import static java.util.Collections.*;   // correct

 

example: name conflict.

import static statics.A.TYPE;  //compile error

import static statics.B.TYPE;  //compile error

can be solved as following:

import statics.A;  //regular import

import statics.B;

int num1 = A.TYPE;

int num2 = B.TYPE;

 

2. Passing Data Among Methods

pass-by-value:  a copy of variable (NOT value) is made and the method receives that copy (create a new reference to the same value). Assignments made in the method does NOT affect the caller.

example 1:

public static void main(String[] args){

  int num = 4;

  newnum(num);

  System.out.println(num);  //4

}

public static void newnum(int num){  //num is only a copy

  num = 8

}

example 2:

public static void main(String[] args) {

  StringBuilder name = new StringBuilder();

  speak(name);

  System.out.println(name);  // Webby, they both points to the same StringBuilder.

}

public static void speak(StringBuilder s) {

  s.append("Webby");

}

 

3. Overloading Methods

Methods with the same name but different type parameters (different type, more types or same types in different order)

example 1:

public void fly(int numMiles){}

public void fly(short numFeets){}

public boolean fly(){return false}  // return types doesn't matter

void fly(){int numMiles, short numFeet}  // access modifier doesn't matter

 

example 2:

public void fly(int[] lengths){}

public void fly(int... lengths){}  // NOT compile, cause JAVA treats varargs as array, so they are considered to be the same method

 

the order to choose the right overloaded method,

-- the most specific parameter list it can find.

-- larger primitive type

-- autoboxed type

-- Varargs

JAVA only do one convention.

public void play(Long l){}

public void play(Long... l){}

play(4);  // compile error, 4 can only be converted to long or Integer, can NOT be converted to Long

play(4L);  //converted to Long

 

4. Creating Constructors

A constructor is a special method which matches the class name but has no return type.

Constructors are used when creating new object.

A constuctor is typically used to initialize instance variables.

The this keyword tells Java you want to reference to an instance variable. 

when there is no name collision, this can be omitted

public class Bunny{

  private int num;

  private String color;

  public Bunny(int newnum, String color){

    num = newnum;  // omit this

    this.color = color;  // this tells JAVA to refer to the instance variable

  }

}

1) Constructors

The default constructor has an empty parameter list and an empty body.

It is only supplied when there is no constructors present.

Private consturctor prevents other classes from initializing the class.

Overloaded constructors often call each other. One common technique is to have each constructor add one parameter until getting to the constructor that does all the work. Why don't all other constructors cite the last constructor directly??

example:

public class Mouse {

  private int numTeeth;

  private int numWhiskers;

  private int weight;

  public Mouse(int weight) {

    this(weight, 16);   // calls constructor with 2 parameters

  }

  public Mouse(int weight, int numTeeth) {

    this(weight, numTeeth, 6);   // calls constructor with 3 parameters

  }

  public Mouse(int weight, int numTeeth, int numWhiskers) {

    this.weight = weight;

    this.numTeeth = numTeeth;

    this.numWhiskers = numWhiskers;

  }

  public void print() {

    System.out.println(weight + " " + numTeeth + " " + numWhiskers);

  }

  public static void main(String[] args) {

    Mouse mouse = new Mouse(15);

    mouse.print();

   }

}

 

5. Final Fields

By the time the constructor completes, all final instance variables must have been set.

 

6. Order of Initialization

-- If there is superclass, initialize it first

-- Static variable declarations and static initializers

-- Instance variable declarations and instance initializers

-- constructors

The four rules apply only if an object is initialized.

If the class is referred without a new call, only rules 1 and 2 apply. The other two rules relates to instances and objects.

example:

public class YetMoreInitializationOrder {   //result is 2 4  6 8 5

  static { add(2);}   // first, 2

  static void add(int num) {System.out.print(num + " ");}   //second

  YetMoreInitializationOrder() {add(5);}   // seventh, 5

  static {add(4); }   // third, 4

  { add(6); }   // fifth, 6

  static { new YetMoreInitializationOrder(); }   // fourth, new starts instance initialization, but have to wait for others completing cause the body is calling constructor

  { add(8); }   //sixth, 8

  public static void main(String[] args) { }

}

 

7. Encapsulating Data

Encapsulation to the rescue. Encapsulation means we set up the class so only methods in the class can refer to the instance variables.

example: the data is private, setter and getter are public.

public class Swan {

  private int numberEggs; // private

  public int getNumberEggs() { // getter 

    return numberEggs;

  }

  public void setNumberEggs(int numberEggs) { // setter

    if (numberEggs >= 0)   // guard condition

      this.numberEggs = numberEggs;

  }

}

1) Rules for Javabeans naming Conventions

-- properties are private

-- getter method begin with is if the property is a boolean

-- getter method begin with get if the property is a not a boolean

-- the setter method begin with set

-- the method name must begin with is/get/set, with the first letter of property in uppercase, then followed by the rest of the property name

2) Creating Immutable Classes

One way to create immutable classes is to omit the setters and specify the initial value by constructors.

example 1:

public class ImmutableSwan {

  private int numberEggs;

  public ImmutableSwan(int numberEggs) {  // immutable data type, when the object is created, it's immutable

    this.numberEggs = numberEggs; }

  public int getNumberEggs() { return numberEggs;}

}

example 2:

public class NotImmutable {

  private StringBuilder builder;

  public NotImmutable(StringBuilder b) {  // mutable data type

    builder = b; 

  }

  public StringBuilder getBuilder() { return builder;}

}

public class test{

  public static void main(String[] args){

    StringBuilder sb = new StringBuilder("initial");

    NotImmutable problem = new NotImmutable(sb);  //pass-by-value, to create a new reference to the same value.

    sb.append(" add");

    StringBuilder gotBuilder = problem.getBuilder();

    gotBuilder.append(" more");

    System.out.println(sb);  //"initial add more"

    System.out.println(gotBuilder);  //"initial add more"

    System.out.println(problem.getBuilder);  //"initial add more"

  }}

To solve the problem in example 2.

-- to make a copy of the mutable object.

builder = new StringBuilder(b);  // for the constructor

return new StringBuilder(builder);  // for the getter

-- to return a immutable object for the getter

builder = new StringBuilder(b);  // for the constructor

return builder.toString();  // for the getter

Encapsulation refers to preventing callers from changing instance variables directly.

Immutability refers to preventing callers from changing the instance vairables at all.

 

8. Writing Simple Lambdas

Functional Programming uses lambda expressions to write code. A lambda expression is a block of code that gets passed around.

It's like an anonymous method.

Deferred execution means that code is specified now but will run later.

1) Lambda Syntax

a -> a.canHop();

(Animal a) -> {return a.canHop();}

It means that Java will call an method with an Animal parameter that returns a boolean value that is a result of a.canHop().

-- the parenthese can only be omitted if there is a single parameter and its type is not explicitly stated.

-- the braces can only be omitted if there is a single statement, and the semicolon and return should be also omitted whild doing so.

(a, b) -> {int a =0; return 5;}  //compile error,  Java doesn't allow us to redeclare a local variable.

(a, b) -> {int c =0; return 5;}  // ok

 Java replies on context when figuring out what lambda expressions means.

We are passing lambda as the second paremeter of method print(). The method expects a CheckTrait as the second parameter. since we are passing a lambda instead, Java tries to match our lambda to that interface.

boolean test(Animal a)

-- since that interface's method takes an Animal, that means that lambda parameter has to be an Animal.

-- since the interface's method returns an boolean, we know lambda returns an boolean.

2) Predicates

Lambdas work with interfaces that have only one method. These are called function interfaces. 

Java provide such an interface for us, called Predicate.

The predicate interface is in the package java.util.function.

public interface Predicate<T>{

  boolean test(T t);

}

example 1:

import java.util.*;

import java.util.function.*;  //import predicate interface

public class test{

  public static void main(String[] args){

    List<String> bunnies = new ArrayList<>(); 

    bunnies.add("long ear");

    bunnies.add("floppy");

    bunnies.add("hoppy");

    System.out.println(bunnies); // [long ear, floppy, hoppy] 

    bunnies.removeIf(s -> s.charAt(0) != 'h');  // define a predicate that takes a string and returns a boolean. the removeif does the rest.

    System.out.println(bunnies); // [hoppy] 

  }}

example 2: print out "match"

import java.util.function.*;

public class Panda {

  int age;

  public static void main(String[] args) {

    Panda p1 = new Panda();

    p1.age = 1;

    check(p1, p -> p.age < 5);  // The lambda expression takes p (Panda) and returns a boolean (result of "p.age<5")

  }

  private static void check(Panda panda, Predicate<Panda> pred) {

    String result = pred.test(panda) ? "match" : "not match";   // In my guess: boolean test(Panda p){ return (p.age<5);}

    System.out.print(result);  // match

}}

 

 

 

 

 

 

 

5. 单引号与双引号的区别

区别1:java中的单引号表示字符,java中的双引号是字符串。

区别2:单引号引的数据一般是char类型的;双引号引的数据 是String类型的。

区别3:java中单引号里面只能放一个字母或数字或符号;java中的双引号里面是0到多个字符构成。所以字符可以直接转换成字符串。字符串需要使用charAt(n) 来获取第几个字符。

char定义时用单引号,只能有一个字母,数字。char c='c';而String用双引号,可以是一个,也可能是多个字母,汉字等。就是所谓的字符串。String s="adsaf";

char只是一个基本类型,而String 可以是一个类,可以直接引用。比如char c='c';不能直接对c调用方法。String s="abc";  这时可以调用s.charAt(0);等方法,因为String是类,这是就是对象的调用了

 

猜你喜欢

转载自www.cnblogs.com/shendehong/p/10660692.html