Today’s Summary:
- Common Data Types:
- Covered: Integer, String, Character, Array
- Not yet covered: List series (lists), Set series (collections), Map series (dictionaries)
- Object-Oriented Programming
- Packages (Python packages and modules)
About Object #
In Python, every class by default inherits from the Object class (all classes are subclasses of Object).
In Java, all classes also by default inherit from the Object class.
A base class can be used to generally refer to the types of its subclasses.
import java.util.Arrays; // Import the java.util.Arrays class, used for array operations, but not used in this program
public class Hello { // Define a public class named Hello
public static void main(String[] args) { // The main method, entry point of the program
// String first = "Joebiden"; // Define a string variable named first and initialize it to "Joebiden"
Object first = new String("Joebiden"); // Define an object variable named first, and initialize it with a String object "Joebiden"
System.out.println(first); // Print the content of the first object, which is the string "Joebiden"
System.out.println(first.getClass()); // Print the class information of the first object, i.e., class java.lang.String
Object second = 2027; // Define an object variable named second, and initialize it with the integer 2027 (autoboxed to Integer)
System.out.println(second); // Print the content of the second object, which is the integer 2027
System.out.println(second.getClass()); // Print the class information of the second object, i.e., class java.lang.Integer
}
}
import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
// Declare an array, elements must be of type int
int[] functionname1 = new int[3];
// Declare an array, elements must be of type String
String[] functionname2 = new String[3];
// Declare an array, elements can be of type int or String (any Object type)
Object[] functionname3 = new Object[3];
functionname3[0] = 83;
functionname3[1] = "joebiden";
}
}
So, if you want to declare an array with mixed types in the future, you can use Object to achieve this.
import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
// v1 refers to a String object
String v1 = new String("ningkong");
String res = v1.toUpperCase();
System.out.println(res);
// v2 is essentially a String object, but declared as Object
Object v2 = new String("ningkong");
String data = (String) v2; // type casting back to String
}
}
import java.util.Arrays;
public class Hello {
public static void func(Object v1) {
// System.out.println(v1);
// System.out.println(v1.getClass());
if (v1 instanceof Integer) {
System.out.println("Integer type");
} else if (v1 instanceof String) {
System.out.println("String type");
} else {
System.out.println("Unknown type");
}
}
public static void main(String[] args) {
func(123);
func("123");
}
}
- In Java, all classes inherit from
Object, andObjectrepresents all types. - Creating Relationships Yourself
ArrayList v1 = new ArrayList();
LinkedList v2 = new LinkedList();
List v1 = new ArrayList();
List v2 = new LinkedList();
Object v1 = new ArrayList();
Object v2 = new LinkedList();
1. Common Data Types ✅ #
1.1 —The List Interface – used to store multiple pieces of data dynamically. #
Similar to a list in Python. ✅
List is an interface, and it has two commonly used implementations (designed to store multiple dynamic data elements).
- ArrayList – storage in contiguous memory addresses (with automatic internal resizing). → This corresponds to the characteristics of Python lists.
- LinkedList – implemented based on a linked list structure (like a bicycle chain). → This does not correspond to Python lists (since Python lists are array-based).
ArrayList v1 = new ArrayList();
v1.add("ningkong");
v1.add("alice");
LinkedList v1 = new LinkedList();
v1.add("boob");
v1.add("ningkong");
In Java, an interface is used to constrain the classes that implement it, requiring them to contain certain members.
interface List {
public void add(Object data); // Methods in an interface do not provide implementations; they only serve as constraints.
}
class ArrayList implements List {
public void add(Object data) {
// Store the data in memory using a contiguous storage approach.
// ..
}
}
class LinkedList implements List {
public void add(Object data) {
// Store the data in memory in the form of a linked list.
// ..
}
}
List v1 = new ArrayList();
v1.add("ningkong");
v1.add("alice");
List v1 = new LinkedList();
v1.add("ningkong");
v1.add("alice");
ArrayList Example:
import java.util.ArrayList;
import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
// By default, ArrayList can store mixed data types if no generic type is specified.
// However, it is recommended to use generics for type safety.
// Example:
// ArrayList <String> data = new ArrayList <String>();
// ArrayList <Object> data = new ArrayList <Object>();
ArrayList data = new ArrayList(); // Create an ArrayList to store different data types
data.add("ningkong"); // Add a String
data.add("alice"); // Add a String
data.add(2027); // Add an Integer
data.add("windows"); // Add a String
// String value1 = data.get(1); // Trying to get the second element (compile error without casting)
// String value2 = (String) data.get(2); // Cast to String (will cause runtime error if type is not String)
// System.out.println("I'm value1: " + value1);
// System.out.println("I'm value2: " + value2);
Object temp = data.get(1); // Get the second element
String value = (String) temp; // Cast to String (safe in this case)
System.out.println(value);
int xo = (int) data.get(2); // Get the third element and cast to int
System.out.println(xo);
data.set(0, "hello"); // Modify the first element
System.out.println(data);
data.remove("bush"); // Try to remove element "bush" (no effect, since it doesn’t exist)
data.remove(0); // Remove the first element
System.out.println("After attempting to remove \"bush\" and removing the first element: " + data);
int size = data.size(); // Get the size of the ArrayList
System.out.println(size);
boolean exists = data.contains("Ningkong"); // Check if a specific element exists (case-sensitive)
System.out.println(exists);
for (Object item : data) { // Iterate over the ArrayList and print each element
System.out.println("Item: " + item);
}
for (int i = 0; i < data.size(); i++) { // Iterate using index
Object item = data.get(i);
System.out.println("Index " + i + " --> " + item);
}
}
}
LinkedList Example:
import java.util.LinkedList;
public class Hello {
public static void main(String[] args) {
// Create a LinkedList to store integers
LinkedList<Integer> v1 = new LinkedList<Integer>();
v1.add(2045); // Add element 2045 to v1
v1.add(2046); // Add element 2046 to v1
// Create a LinkedList to store objects of any data type
LinkedList<Object> v2 = new LinkedList<Object>();
v2.add("United States"); // Add a string to v2
v2.add("North America"); // Add a string to v2
v2.add(2009); // Add an integer to v2
v2.add(2025); // Add an integer to v2
// v2.remove(1); // Try to remove the element at index 1
// v2.remove("North America"); // Try to remove the element "North America"
v2.set(2, "Google"); // Replace the third element
v2.push("Microsoft"); // Add an element to the beginning
// Iterate over the LinkedList and print each element
for (int i = 0; i < v2.size(); i++) {
Object item = v2.get(i);
System.out.println(item);
}
// Iterate over the LinkedList using an enhanced for loop
for (Object item : v2) {
System.out.println(item);
}
}
}
about iterator:
import java.util.*;
public class Hello {
public static void main(String[] args) {
ArrayList s1 = new ArrayList(); // Create an ArrayList called s1
s1.add("Facebook"); // Add "Facebook" to the list
s1.add("Qualcomm"); // Add "Qualcomm" to the list
s1.add("Cisco"); // Add "Cisco" to the list
Iterator it = s1.iterator(); // Create an iterator for the list
while (it.hasNext()) { // While there are more elements
String item = (String) it.next(); // Get the next element as a string
System.out.println(item); // Print the element
}
}
}
1.2 — Set Interface — Multi-Element Collection #
Set is an interface in Java. Two common classes that implement this interface are used to represent collections of elements without duplicates.
- HashSet – removes duplicates, does not preserve order.
- TreeSet – removes duplicates and maintains sorted order (by ASCII or Unicode). [Note: Different data types cannot be directly compared in a
TreeSet.]
import java.util.*;
public class Hello {
public static void main(String[] args) {
// Different ways to declare a Set:
// HashSet s1 = new HashSet();
// Set s1 = new HashSet();
// HashSet <String> s1 = new HashSet <String>();
HashSet s1 = new HashSet();
s1.add("north");
s1.add("south");
s1.add("north"); // duplicate ignored
s1.add("east");
s1.add(2025); // allowed, since HashSet accepts mixed types
System.out.println(s1); // Output example: [north, south, east, 2025]
// Initialize HashSet with elements directly
HashSet s2 = new HashSet() {{
add("california");
add("newyork");
add("canada");
}};
System.out.println(s2);
// Different ways to declare a TreeSet:
// Set s3 = new TreeSet();
// TreeSet <String> s3 = new TreeSet <String>();
TreeSet s3 = new TreeSet();
s3.add("north");
s3.add("south");
s3.add("north"); // duplicate ignored
s3.add("east");
// s3.add(2027); // Not allowed, since TreeSet requires comparable elements of the same type
System.out.println(s3); // Output: [east, north, south]
// Initialize TreeSet with elements directly
TreeSet s4 = new TreeSet() {{
add("Britsh"); // (probably meant "British")
add("French");
add("Germany");
add("French"); // duplicate ignored
}};
System.out.println(s4); // Output: [Britsh, French, Germany]
}
}
On Union, Intersection, and Difference:
import java.util.*;
public class Hello {
public static void main(String[] args) {
// Set s1 = new HashSet();
HashSet s1 = new HashSet();
s1.add("push");
s1.add("pop");
s1.add("arm64");
s1.remove("pop");
System.out.println(s1); // [push, arm64]
boolean exists = s1.contains("");
System.out.println(exists);
HashSet s2 = new HashSet();
s2.add(2025);
s2.add(2026);
HashSet v1 = new HashSet(); // initially empty
v1.addAll(s1);
v1.retainAll(s2); // intersection (s1 ∩ s2)
System.out.println(v1);
HashSet v2 = new HashSet();
v2.addAll(s1);
v2.addAll(s2); // union (s1 ∪ s2)
System.out.println(v2);
HashSet v3 = new HashSet();
v3.addAll(s1);
v3.removeAll(s2); // difference (s1 - s2)
System.out.println(v3);
HashSet v4 = new HashSet();
v4.addAll(s2);
v4.removeAll(s1); // difference (s2 - s1)
System.out.println(v4);
}
}
About TreeSet:
import java.util.*;
public class Hello {
public static void main(String[] args) {
TreeSet s1 = new TreeSet();
s1.add("billgates");
s1.add("stevejobs");
s1.add("elonmusk");
for (Object item : s1) {
System.out.println(item);
}
}
}
About Iterators:
import java.util.*;
public class Hello {
public static void main(String[] args) {
TreeSet s1 = new TreeSet();
s1.add("north");
s1.add("south");
s1.add("west");
Iterator it = s1.iterator();
while (it.hasNext()) {
String item = (String) it.next();
System.out.println(item);
}
}
}
1.3 — The Map Interface — Storing Key-Value Pairs #
Map is an interface, and there are two common classes that implement this interface, used to store key-value pairs:
- HashMap: unordered.
- TreeMap: ordered by key by default (commonly used). # In Python, you need to handle the problem of key sorting yourself.
v4 = {
"aid":2024,
"cid":2025,
"wid":2046
}
# 1. Sort by key
# data = ["{}={}".format(key, v4[key]) for key in sorted(v4.keys())]
# 2. Then concatenate
# result = "&".join(data)
result = "&".join(["{}={}".format(key, v4[key]) for key in sorted(v4.keys())])
print(result)
/**
* @author calleng
* @version 1.0
* @date 2024/07/05 18:44
* @desc Demonstrates different ways to create and use HashMaps in Java
*/
import java.util.HashMap;
public class LookUp {
public static void main(String[] args) {
// Example 1: Raw HashMap without generics
HashMap h1 = new HashMap();
h1.put("name","bob");
h1.put("age",39);
h1.put("gender","male");
System.out.println(h1); // {gender = male, name = bob, age = 39}
// Example 2: HashMap with generics (String, String)
HashMap<String,String> h2 = new HashMap<String,String>();
h2.put("name","alice");
h2.put("age","18");
h2.put("gender","female");
System.out.println(h2); // {gender = female, name = alice, age = 18} ✅ corrected comment
// Example 3: Anonymous inner class with initializer block
HashMap<String,String> h3 = new HashMap<String,String>(){
{
put("name","charles");
put("age","42");
put("gender","male");
}
};
System.out.println(h3); // {gender = male, name = charles, age = 42}
}
}
/**
* @author calleng
* @version 1.0
* @date 2024/07/05 18:44
* @desc Example of using HashMap and Map in Java
*/
import java.util.HashMap;
import java.util.Map;
public class LookUp {
public static void main(String[] args) {
// Raw HashMap without generics
HashMap h1 = new HashMap();
h1.put("name","timcook");
h1.put("age",64);
h1.put("gender","male");
System.out.println(h1); // {gender = male, name = timcook, age = 64}
// HashMap with <String, String>
HashMap<String,String> h2 = new HashMap<String,String>();
h2.put("name","masayoshison");
h2.put("age","68");
h2.put("gender","male");
System.out.println(h2); // {gender = male, name = masayoshison, age = 68}
// ❌ Problem here:
// You declared Map <String, Integer>, but tried to put String values ("jackma", "male").
// This will cause a compilation error, because "jackma" and "male" are not Integers.
// Correct approach should be <String, String> if you want to store string values.
/*
Map <String,Integer> h3 = new HashMap <String,Integer>(){
{
put("name", "jackma"); // ERROR: "jackma" is not Integer
put("age",60); // OK
put("gender", "male"); // ERROR: "male" is not Integer
}
};
System.out.println("Direct map usage -> " + h3);
*/
// ❌ Same problem: declared HashMap <String, Integer> but storing Strings
/*
HashMap <String,Integer> h4 = new HashMap <String,Integer>(){
{
put("name", "samaltman"); // ERROR
put("age",40); // OK
put("gender", "male"); // ERROR
}
};
System.out.println("String, Integer type -> " + h4);
*/
}
}
Common Operations:
import java.util.*;
public class Hello {
public static void main(String[] args) {
TreeMap h1 = new TreeMap(); // Changed to TreeMap
h1.put("name", "alex");
h1.put("age", "18");
h1.put("hobby", "openai");
h1.put("academy", "sandford");
h1.remove("age");
int size = h1.size();
Object value = h1.get("name"); // If the key does not exist, returns null
System.out.println(value);
boolean existsKey = h1.containsKey("age");
boolean existsValue = h1.containsValue("alex");
h1.replace("name", "timecook");
System.out.println(h1);
// Loop: Example 1
// { ("name", "samaltman"), ("age", "40") }
Set<Map.Entry<String, String>> s1 = h1.entrySet();
Iterator it1 = s1.iterator();
while (it1.hasNext()) {
// ("name", "samaltman")
Map.Entry<String, String> entry = (Map.Entry<String, String>) it1.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
}
// Loop: Example 2
Set s2 = h1.entrySet();
Iterator it2 = s2.iterator();
while (it2.hasNext()) {
Map.Entry entry = (Map.Entry) it2.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
}
// Loop: Example 3
TreeMap<String, String> h2 = new TreeMap<String, String>(); // Changed to TreeMap
h2.put("name", "billgates");
h2.put("age", "69");
for (Map.Entry<String, String> entry : h2.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
}
// Loop: Example 4
TreeMap h3 = new TreeMap(); // Changed to TreeMap
h3.put("name", "joebiden");
h3.put("age", 82);
for (Object entry : h3.entrySet()) {
Map.Entry<String, Object> entryMap = (Map.Entry<String, Object>) entry;
String k = entryMap.getKey();
Object v = entryMap.getValue();
if (v instanceof Integer) {
System.out.println("Number: " + Integer.toString((Integer) v));
} else if (v instanceof String) {
System.out.println("String: " + (String) v);
} else {
System.out.println("Unknown type: " + v.toString());
}
}
}
}
2. Object-Oriented Programming #
- Python: Supports both functional and object-oriented programming.
- Java: Purely object-oriented.
2.1 Classes and Objects #
class Person {
// Instance variables
public String name;
public Integer age;
// Constructor 1
public Person() {
this.name = "Donald Trump";
this.age = 79;
}
}
Person obj = new Person();
class Person:
# Initialization method:
# 1. __new__ method: constructor method that creates an empty object
# 2. __init__ method: initializer
def __init__(self):
self.name = "obama"
self.age = 64
obj = Person()
class Person {
// Instance variables
public String name;
public Integer age;
public String email;
// Constructor 1
public Person() {
this.name = "Obama";
this.age = 64;
}
// Constructor 2
public Person(String name, Integer age) {
this.name = name;
this.age = age;
this.email = "google@yahoo.com";
}
// Constructor 3
public Person(String name, String email) {
this.name = name;
this.age = 83;
this.email = email;
}
}
Person obj1 = new Person("donald trump", 79);
Person obj2 = new Person();
class Person {
// Instance variables
public String fullName;
public Integer age;
public String emailAddress;
// Constructor 1 (no arguments)
public Person() {
this.fullName = "Eric";
this.age = 99999;
}
// Constructor 2 (name + age)
public Person(String fullName, Integer age) {
this.fullName = fullName;
this.age = age;
this.emailAddress = "example@live.com";
}
// Constructor 3 (name + email)
public Person(String fullName, String emailAddress) {
this.fullName = fullName;
this.age = 83;
this.emailAddress = emailAddress;
}
// Method (overloaded) - no parameters
public void introduce() {
System.out.println(this.fullName);
}
// Method (overloaded) - with prefix
public void introduce(String prefix) {
String text = String.format("%s%s", prefix, this.fullName);
System.out.println(text);
}
}
public class Hello {
public static void main(String[] args) {
// When instantiating objects, encapsulation is demonstrated
Person person1 = new Person();
Person person2 = new Person("Alex Johnson", 73);
Person person3 = new Person("Tony Smith", "tony.smith@example.com");
person1.introduce();
person1.introduce("Hello, ");
person2.introduce();
person2.introduce("Hello, ");
person3.introduce();
person3.introduce("Hello, ");
}
}
2.3 Static Members — Static Belong to the Class; Non-Static Belong to the Object #
class Person:
school_name = "Tsinghua University" # Static variable (belongs to the class, independent of any object)
def __init__(self):
self.full_name = "Alice" # Instance variable (belongs to the object)
# Access the static variable directly via the class
print(Person.school_name)
# 1. Create an empty object in memory
# 2. Automatically call the constructor (__init__)
student = Person()
print(student.full_name) # Access instance variable
print(student.school_name) # Access static variable (still works through the object)
class Person {
// Static variable
public static String city = "New York";
// Instance variables
public String name;
public Integer age;
// Constructor 1
public Person() {
this.name = "Alice";
this.age = 30;
}
// Instance method
public void showInfo() {
System.out.println("Name: " + this.name + ", Age: " + this.age + ", City: " + city);
}
// Static method
public static void showData() {
System.out.println("All persons live in " + city);
}
}
// Access static variable
Person.city;
// Call static method
Person.showData();
// Create object
Person obj = new Person();
obj.name;
obj.age;
obj.showInfo();
Essence: Static members belong to the class, while non-static members belong to the object.
2.3 Inheritance – A Class Only Supports Single Inheritance #
In Java, inheritance only supports single inheritance.It does not support multiple inheritance, but it does support implementing multiple interfaces.
//Overloading: When a class contains multiple methods with the same method name but with different numbers or types of parameters. //Overriding: When a subclass redefines a method that already exists in its parent class.
class Animal {
...
}
class Vehicle {
...
}
// Single inheritance
class Dog extends Animal {
...
}
interface Addable {
public void add();
}
interface Multipliable {
public void multiply();
}
class Calculator implements Addable, Multipliable {
public void add() {
// implementation
}
public void multiply() {
// implementation
}
}
In Python, multiple inheritance is supported:
class Dog(Animal, Pet):
pass
class Calculator(Addable, Multipliable):
pass
class Account {
public String email;
public Account(String email) {
this.email = email;
}
public String getAccountInfo() {
return String.format("%s", this.email);
}
}
// Example usage:
// Account acc = new Account("test@example.com");
// acc.email; // "test@example.com"
// acc.getAccountInfo(); // "test@example.com"
class Person extends Account {
public String name;
public Integer age;
public Person(String name, Integer age, String email) {
super(email); // calls parent constructor
this.name = name;
this.age = age;
}
public String getProfile(String prefix) {
return String.format("%s-%d-%s", this.name, this.age, this.email);
}
}
// Example usage:
Person president = new Person("Joe Biden", 82, "joebiden@google.com");
// president.name; // "Joe Biden"
// president.age; // 82
// president.email; // "joebiden@google.com"
// president.getProfile("prefix"); // "Joe Biden-82-joebiden@google.com"
// president.getAccountInfo(); // "joebiden@google.com"
Using a parent class to refer to all of its subclasses.
// Base class
class Base {
public void show() {
System.out.println("This is Base class");
}
}
// Subclass Person extends Base
class Person extends Base {
@Override
public void show() {
System.out.println("This is Person class");
}
}
public class Hello {
public static void main(String[] args) {
Person personObj = new Person();
personObj.show(); // Output: This is Person class
Base baseObj = new Base();
baseObj.show(); // Output: This is Base class
Base polymorphicObj = new Person();
polymorphicObj.show(); // Output: This is Person class (polymorphism)
}
}
Example with Constructor and Fields
// Base class
class Base {
public String email;
public Base(String email) {
this.email = email;
}
public void getSubInfo() {
System.out.println("Base Info: " + email);
}
}
// Person class inherits from Base
class Person extends Base {
public String name;
public int age;
public Person(String name, int age, String email) {
super(email); // call parent constructor
this.name = name;
this.age = age;
}
@Override
public void getSubInfo() {
System.out.println("Person Info: " + name + ", " + age + ", " + email);
}
}
public class Hello {
public static void handler(Base obj) {
obj.getSubInfo(); // Demonstrates polymorphism
}
public static void main(String[] args) {
Person person1 = new Person("Alice", 30, "alice@example.com");
handler(person1); // Output: Person Info: Alice, 30, alice@example.com
Base base1 = new Base("contact@example.com");
handler(base1); // Output: Base Info: contact@example.com
Base person2AsBase = new Person("Bob", 25, "bob@example.com");
handler(person2AsBase); // Output: Person Info: Bob, 25, bob@example.com
}
}
2.4 Interfaces — A Class Can Implement Multiple Interfaces #
- Constrains the implementing class by requiring it to include specific members
- Generally refers to the objects created by the implementing class
- Contains no implementation itself
- A single class can implement multiple interfaces
interface MessageService {
public void send();
}
// The WeChat class "implements" the MessageService interface
class WeChat implements MessageService {
public void send() {
System.out.println("Sending a message via WeChat");
}
}
class DingTalk implements MessageService {
public void send() {
System.out.println("Sending a message via DingTalk");
}
}
class SMS implements MessageService {
public void send() {
System.out.println("Sending a text message via SMS");
}
}
// Example usage
WeChat wechatService = new WeChat();
MessageService messageService = new WeChat();
public class Hello {
// Polymorphism -> multiple forms of IMessage
public static void handleMessage(IMessage message) {
message.send();
}
// Main function
public static void main(String[] args) {
Sms smsMessage = new Sms();
handleMessage(smsMessage);
}
}
In Java: multiple class inheritance is not supported; implementing multiple interfaces is supported.
interface PersonActions {
void speak();
void speak(int age);
void describe(String details);
}
interface UserActions {
String generateUserId(int id);
}
class User {
public String fullName;
public Integer age;
public String email;
public User(String fullName, Integer age, String email) {
this.fullName = fullName;
this.age = age;
this.email = email;
}
public String getContactInfo() {
return String.format("Email: %s", this.email);
}
}
class Person extends User implements UserActions, PersonActions {
public Person(String fullName, Integer age, String email) {
super(fullName, age, email);
}
public String getProfile() {
return String.format("Name: %s | Age: %d | Email: %s", this.fullName, this.age, this.email);
}
@Override
public void speak() {
System.out.println("Speaking with no parameters.");
}
@Override
public void speak(int age) {
System.out.println("Speaking with age parameter: " + age);
}
@Override
public void describe(String details) {
System.out.println("Description: " + details);
}
@Override
public String generateUserId(int id) {
return "USER-" + id;
}
}
public class HelloWorld {
public static void main(String[] args) {
Person person = new Person("Donald Trump", 79, "donaldtrump@live.com");
person.speak();
person.speak(79);
person.describe("Former U.S. President");
System.out.println(person.getProfile());
System.out.println("Generated ID: " + person.generateUserId(2026));
}
}
Suppose I am doing reverse engineering and have obtained an APK. I search for a keyword, such as printInfo, and locate an interface:
interface Person {
public void showName();
public void showAge(int age);
public void printInfo(String details);
}
The next step is to check which classes implement the Person interface.
- If only one class implements
Person, then that class is the target. - If multiple classes implement the
Personinterface, you need to filter and determine which specific class is the one of interest.
2.5 Abstraction — (Inheritance + Interfaces)
) #
// Abstract class
abstract class MediaPlayer {
// Abstract method (forces subclasses to implement this method)
public abstract void play(String trackName);
// Normal method
public void stop() {
System.out.println("Stop");
}
}
// Subclass
class AudioPlayer extends MediaPlayer {
@Override
public void play(String trackName) {
System.out.println("Playing: " + trackName);
}
}
public class Main {
public static void main(String[] args) {
AudioPlayer player = new AudioPlayer();
player.stop();
player.play("Song A");
// Base class reference can also point to a subclass
MediaPlayer genericPlayer = new AudioPlayer();
genericPlayer.play("Song B");
}
}
Note: A base class reference can also generally refer to its subclasses.
3.Package Concept #
src
├── MainApp.java
└── utils
└── MessageUtils.java
// MainApp.java
import utils.MessageUtils;
public class MainApp {
public static void main(String[] args) {
String message = MessageUtils.getMessage();
System.out.println(message);
}
}
// MessageUtils.java
package utils;
public class MessageUtils {
public static String getMessage() {
return "Joe Biden";
}
}
Class Modifiers
- public – Public, can be accessed by anyone from any package.
- default – No modifier; can only be accessed within the same package.
Class Member Modifiers
- public – Public, accessible to all classes that can access the class itself.
- private – Private, accessible only within the same class.
- protected – Accessible within the same package, or by subclasses (even if they are in a different package).
- default – No modifier; accessible only within the same package.
Purpose: Using modifiers makes the calling and access relationships clearer. (However, in many projects, these modifiers are not always used in a very strict or “textbook” way.)
