IT234 Object Oriented Programming with Java

Object Oriented Programming with JavaUnit 147 min read

Character Handling, Sealed Classes & Java Text Processing

Unit 14 of Object Oriented Programming with Java covers Unicode character encoding, Java’s char type, text manipulation methods, and sealed classes—including their syntax, restrictions, and use cases in secure hierarchies.

TAKEAWAYS:

  • Java’s char type uses Unicode (UTF-16), supporting 65,536 characters via surrogate pairs for extended symbols.
  • Sealed classes restrict which classes can extend them, enabling controlled inheritance hierarchies (e.g., payment gateways).
  • Text processing methods like String.charAt(), String.codePointAt(), and Character.isDigit() handle Unicode efficiently.
  • Wrapper classes (Character, String) convert between primitive char and objects for collections or APIs.
  • Sealed hierarchies improve security by preventing unauthorized subclassing (e.g., financial transaction types).
  • Exam focus: Trace character operations (e.g., charAt loops) and sealed class syntax with permits.

Character Handling in Java

Java treats text as sequences of Unicode characters, stored in char (16-bit UTF-16) or String objects. Unlike ASCII (7-bit), Unicode supports global scripts, emojis, and symbols.

1. The char Type and Unicode

  • Range: '\u0000' to '\uffff' (65,536 code points).
  • Surrogate pairs: Characters beyond '\uFFFF' (e.g., emojis) use two char values (high + low surrogate).
  • Example: The Nepali letter "क" (\u0915) fits in one char, but "😊" (U+1F60A) requires a surrogate pair.
char nepaliChar = '\u0915';  // Single char for "क"
char[] emojiPair = {'\uD83D', '\uDE0A'};  // Surrogate pair for "😊"

2. Key Character Methods

Method Purpose Example
charAt(int index) Get character at position "नमस्ते".charAt(0) → 'न'
codePointAt(int index) Get Unicode code point "😊".codePointAt(0) → 128522
isLetter(char c) Check if alphabetic Character.isLetter('क') → true
toUpperCase(char c) Convert to uppercase Character.toUpperCase('a') → 'A'

Worked Example: Nepali Vowel Checker

public static boolean isNepaliVowel(char c) {
    return (c >= '\u0905' && c <= '\u0939');  // Nepali vowel range
}

Trace:

Input (c) c >= '\u0905' c <= '\u0939' Result
'अ' true true true
'क' false true false

Sealed Classes: Controlled Inheritance

Sealed classes restrict subclasses to a predefined set, improving security and design clarity.

1. Syntax

public sealed abstract class PaymentMethod permits CreditCard, UPI, Cash {
    // Common fields/methods
}

public final class CreditCard extends PaymentMethod { /* ... */ }
public non-sealed class UPI extends PaymentMethod { /* ... */ }  // Can be extended

2. Permissions

  • permits: Lists allowed subclasses (e.g., CreditCard, UPI).
  • final: Prevents further extension (e.g., CreditCard).
  • non-sealed: Allows subclasses to be extended (e.g., UPI → PhonePe, GooglePay).

Example: Daraz Payment Gateway

sealed interface PaymentGateway permits Ewallet, BankTransfer, COD {
    void process(double amount);
}

final class Ewallet implements PaymentGateway { /* Khalti, eSewa */ }
non-sealed class BankTransfer implements PaymentGateway { /* NMB, SBI */ }

Mermaid Diagram: Sealed Hierarchy for Daraz

classDiagram
    class PaymentGateway {
        <<sealed>>
        +process(amount: double)
    }
    class Ewallet {
        <<final>>
    }
    class BankTransfer {
        <<non-sealed>>
    }
    class SBI {
        <<final>>
    }
    PaymentGateway <|-- Ewallet
    PaymentGateway <|-- BankTransfer
    BankTransfer <|-- SBI

In the Real World

  1. Khalti/eSewa Apps

    • Sealed classes enforce valid payment methods (e.g., UPI, CreditCard). If a developer tries to add BitcoinPayment, the compiler blocks it unless permitted.
    • Character handling: Validates Nepali user names (e.g., checks for '\u0900'–'\u097F' ranges).
  2. Ncell’s USSD Menu

    • Unicode support: Displays Nepali text (e.g., "बिल तिर्नुहोस्") via char arrays in the USSD parser.
    • Sealed classes: Restricts USSD command types to BalanceCheck, Recharge, DataBundle (prevents malicious commands).
  3. NEPSE Stock Ticker

    • Character methods: Parses stock symbols (e.g., "NTC" → charAt(0) gives 'N').
    • Wrapper classes: Converts char to String for JSON APIs (e.g., Character.toString(symbol)).

Text Processing with String and Character

1. Common Pitfalls

  • char vs. String: char is a single Unicode code unit; String is an immutable sequence.
  • Surrogate pairs: Use codePointAt()/codePointBefore() for emojis or combining characters (e.g., "a\u030A" = 'å').

Example: Count Nepali Consonants

public static int countNepaliConsonants(String text) {
    int count = 0;
    for (int i = 0; i < text.length(); i++) {
        char c = text.charAt(i);
        if (Character.isLetter(c) && c >= '\u0915' && c <= '\u0963') {
            count++;
        }
    }
    return count;
}

Trace for "काठमाडौँ":

Index charAt(i) isLetter >= '\u0915' <= '\u0963' Count
0 'क' true true true 1
1 'ा' true false false 1
2 'ठ' true true true 2
... ... ... ... ... 4

Wrapper Class: Character

Converts char to objects for collections or APIs (e.g., Character.valueOf('A')).

Method Example
Character.isDigit('5') true
Character.toString('A') "A" (as String)
Character.compare('a', 'A') -32 (ASCII difference)

Example: Validate Ncell Phone Number

public static boolean isValidNcellNumber(String number) {
    if (number.length() != 10) return false;
    for (char c : number.toCharArray()) {
        if (!Character.isDigit(c)) return false;
    }
    return number.startsWith("98");
}

Trace for "9801234567":

Step Result
length() == 10 true
startsWith("98") true
All isDigit(c) true
Final true

Exam Tip

  1. Character Questions (3–5 marks)

    • Do: Trace loops using charAt()/codePointAt() with Unicode ranges (e.g., Nepali vowels).
    • Avoid: Assuming char is ASCII (e.g., 'क' > 'a' is false).
    • Example: Given "नमस्ते", write code to count vowels using Character.isLetter() + range checks.
  2. Sealed Classes (4–6 marks)

    • Syntax: Remember permits, final, and non-sealed.
    • Design: Justify why a hierarchy should be sealed (e.g., "to prevent invalid transaction types").
    • Example: For a Vehicle sealed class, list permitted subclasses (Car, Bike) and mark one as final.
  3. Common Pitfalls

    • Surrogates: Use codePointAt() for emojis, not charAt().
    • Immutability: String methods return new objects (e.g., toUpperCase()).
    • Wrapper vs. Primitive: Character methods work on char primitives; String methods work on objects.

Visual Summary

flowchart TD
    A["char Handling"] --> B["Unicode<br/>Surrogate Pairs"]
    A --> C["String Methods<br/>charAt, codePointAt"]
    D["Sealed Classes"] --> E["permits Clause"]
    D --> F["final/non-sealed<br/>Restrictions"]
    G["Real-World"] --> H["Khalti<br/>Payment Validation"]
    G --> I["Ncell<br/>USSD Text"]

Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 14.

Discussion

Loading…