name: inverse layout: true class: center, middle, inverse --- # [CSE 340 (Spring 23)](/courses/cse340/23sp/docs) ## Advanced Java --- layout: false # Roadmap - Java code style - String Formatting - Inheritance - Switch/Enums - Generics - Anonymous Inner Classes - Lambdas (and `::` notation) - Android Studio Demo --- # Style Conventions for Android/Java Source: AOSP (Android Open Source Project) [Code Style](http://source.android.com/source/code-style.html#follow-field-naming-conventions) .left-column50[ Field Naming Conventions: - Non-public, non-static field names start with ‘m’. - private float mCircleRadius, mThumbRadius; - Static field names start with ‘s’. - Other fields start with a lowercase letter. - (Constants) public static final fields are ALL_CAPS_WITH_UNDERSCORES. ] .right-column50[ Other things to note: - Limit line length to <= 100 characters long (with the exception of comments with URLs or import statements) - Methods are ideally <= 40 lines long. Otherwise, consider breaking it up. ] --- # String Formatting See [this](http://www.java2s.com/Tutorials/Java/Data_Format/Java_Format_Specifier.htm) documentation for format specifiers ```java String str = "Lauren Bricker"; String professorName = String.format("The Professor's name is %s", str); String floatDemo = String.format("Value is %f", 92.00134); ``` In Android... you will stick the static part of your string values in *res/values/strings.xml* ([String Resources](https://developer.android.com/guide/topics/resources/string-resource)) - Use [getString(R.string.my_string_name)](https://developer.android.com/reference/android/content/Context#getString(int) in Java - Note that R.string.string_name returns its int unique resource ID, not the string's actual value --- # Inheritance .left-column50[ Interfaces: a promise that you will implement these methods - Interfaces can only implement other interfaces - 1 class can implement many interfaces - Methods do NOT have a body/implementation - Examples: Comparable interface ] --- # [Inheritance](https://courses.cs.washington.edu/courses/cse331/20wi/lectures/lec12-subtyping.pdf) .left-column50[ Regular class: fully defined behaviors that you want to add to - All functions in the parent class have been implemented and are inherited - Usually would use this to add more specific behavior by changing implementation or adding new methods ] -- .right-column50[ Abstract classes: like interfaces but has some fully implemented methods as well - May have abstract functions (only defined in subclasses, like interfaces) - Also allows standard member variables and functions - Examples: Pets all have a name (member variable), are adopted (function) but eat different foods (abstract function defined only in subclasses) ] --- # Inheritance common errors and tips Be careful - Don't accidentally redefine a variable you inherited - Use the same method signature (return types and parameter types) when overriding inherited methods - These errors might lead to undefined and weird behaviors! :( Remember - You can only subclass one class, but you can implement as many interfaces as you want - Subclasses can access and change public and protected member variables of parent - You must implement interface methods and all abstract superclass methods --- # Switch Statements A form of a conditional with different execution paths ```java public enum EssentialGeometry { INSIDE, ON_EDGE, OUTSIDE }; ... EssentialGeometry where = EssentialGeometry.INSIDE; switch (where) { case ON_EDGE: // do the edgy things break; // and skip everything after this case INSIDE: // do the inside things but also fall through // and do the OUTSIDE things because no break statement; case OUTSIDE: // do the outside things break; // and skip everything after this default: // do default things // automatically falls through } ``` --- # Enums An enum type is a special data type that restricts a variable to be a set of predefined constants ```java public enum EssentialGeometry { INSIDE, OUTSIDE }; ... EssentialGeometry where = EssentialGeometry.INSIDE; ``` --- # Generics Basically, abstraction over types ```java Point
, Point
// Type abstraction: abstract over element type Interface List
{ // Lets us use types such as: Boolean add(E n); // List
E get(int index); // List
} // List
> ``` --- # [Anonymous Inner Classes](https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html) (1/3) - What: Non-static class that’s nested inside another class. - Don’t have their own name. - Looks like a constructor except there’s a class definition contained inside. - Why: Often used to make an instance of an object that has slightly different methods of another class or interface. - This way, you don’t have to actually make a subclass of a class. - When: Used in some of our HW when implementing “listeners” --- # Anonymous Inner Classes (2/3) ```java public class ExActivity extends AppCompatActivity { private View.OnClickListener mClickListener = new View.OnClickListener() { public void onClick(View v) { if (mButton!=v) { return; } } }; // remember to end this statement with a semicolon } ``` --- # Anonymous Inner Classes (3/3) Digging deeper: Creating an anonymous inner class
```java private View.OnClickListener mClickListener = new View.OnClickListener() {...} ``` --- # Anonymous Inner Classes (3/3) ```java private View.OnClickListener mClickListener = new View.OnClickListener() {...} ``` .left-column50[ `private` -- it's only available inside the class that contains it (e.g. `ExampleActivity`) `View.OnClickListener` -- the variable type ([Documentation](https://developer.android.com/reference/android/view/View.OnClickListener)), a nested class in `View` `mClickListener` is the variable name which is being set to... ] .right-column50[ `View.OnClickListener` is an anonymous object from an abstract class - The one method that you MUST implement (in order to create a new object of this type) is `onClick`, which overrides the abstract method ] --- # [Lambdas](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) What are Lambda expressions in Java? - What: A short block of code that takes in parameters and performs an expression. - ex: (parameter1, parameter2) -> { code code code… optional return something } - Think of it as using code as data - Why: Useful for anonymous classes and functional interfaces. - Allows compact instances of single method classes - This will come up later in the course when dealing with callbacks! - Once instantiated, you can re-use it. Treat it like a function. --- # Lambda Simple Example .left-column50[ An example functional interface ```java interface FuncInter1 { int operation(int a, int b); } ... // Implementing interface w/ lambda function FuncInter1 add = (int x, int y) -> x + y; ``` ] .right-column50[ You can reuse this now! - `add.operation(2, 3)` returns 5 - Functional interfaces have exactly 1 abstract method (1 functionality) in the interface - Can mark with @FunctionalInterface to let compiler know that it is one (gives an error if > 1 method inside) - Functional interfaces can be used with lambda ] --- # Lambda Example with Android Listeners ```java myButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("debug", "Button clicked"); } }); ```
↓
```java myButton.setOnClickListener( v -> Log.d("debug", "Button clicked"); ); ``` --- # Even more shorthand, `::` operator - What: :: is a reference to a method from a certain class - Simpler way to write a lambda expression - Syntax of “::” operator:
::
- Example: ```java numList.forEach(e -> System.out.print(e)); ``` - This does the same thing: `numList.forEach(System.out::print)` --- # Lack of main() in Android Java? - In Android, there is no `main()` - “start” or “launchpoint” is within a subclass of the `Activity` class - onCreate method - In Doodle, notice how `Part1ActivityA`, `Part1ActivityB`, and `Part2Activity` all extend `AbstractMainActivity` - Unlike `main()`, `onCreate()` can be called multiple times (ex: the user kills the process but then navigates back to it). ```java @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } ``` --- # Android Studio Demo (Cool tips and tricks) 0. In general, [Keyboard Shortcuts](https://developer.android.com/studio/intro/keyboard-shortcuts) 1. Search across whole project 2. Extract string resource 3. Inspect Code 4. Android Device command line tool ([adb](https://developer.android.com/studio/command-line/adb)) - adb devices -l (print serial number and state) - adb -s emulator-5555 install helloWorld.apk (install on emulator this apk file) - adb kill-server (terminate adb server) 5. Java Project in Android Studio demo