der Universität Oldenburg

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

der Universität Oldenburg
der Universität Oldenburg
Objektorientierte Programmierung
der Universität Oldenburg
Imperative Programmierung
der Universität Oldenburg
Imperative Programmierung
der Universität Oldenburg
der Universität Oldenburg
DVG Dateien Dateien. DVG Dateien 2 Die Klasse File Die Klasse File stellt die Verbindung zwischen dem Filesystem des Rechners und dem.
DVG Einfache Klassen Einfache Klassen. DVG Einfache Klassen 2 Strukturen Beispiel: Personendaten bestehen aus –String name –String vorname.
Kapselung , toString , equals , Java API
der Universität Oldenburg
Imperative Programmierung -Entwicklungswerkzeuge
Objektorientierte Programmierung
Programmierkurs Java WS 98/99 Vorlesung 15 Dietrich Boles 17/02/99Seite 1 Programmierkurs Java Vorlesung im WS 1998/1999 am FB Informatik der Universität.
der Universität Oldenburg
der Universität Oldenburg
der Universität Oldenburg
Abstrakte Klassen HS Merseburg (FH) WS 06/07.
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
Indirekte Adressierung
Java: Referenzen und Zeichenketten
FH-Hof Java Packages Richard Göbel. FH-Hof Das Modulkonzept für Java Packages dienen zur Strukturierung größerer Java- Programme Ein Package kann: eigene.
Java: Grundlagen der Objektorientierung
Ein Beispiel in Java.
Benötigte Applets Startseite: in HTML-Format Applet auf der Startseite Das Applet, das auf der Startseite geladen wird, wird die vier Buttons und die eine.
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 6 Model-View-Controler als Grundlage für Nutzerschnittstellen Sommersemester 2003 Lars Bernard.
Sommersemester 2004 Jan Drewnak Entwicklung und Einsatz von Geosoftware I Praktikum Sitzung X1 Sitzung X1: Packages & Wiederholung.
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 3 Klassen, Objekte, Arrays und Kontrollstrukturen Sommersemester 2003 Lars Bernard.
Imperative Programmierung Funktionen und Parameter
Objektorientierte Programmierung JDK-Klassenbibliothek
Java-Kurs - 2. Übung Entwicklungsumgebung Struktur von Programmen
Java-Kurs - 7. Übung Besprechung der Hausaufgabe Referenzvariablen
Programmieren mit JAVA
Programmieren mit JAVA
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
PKJ 2005/1 Stefan Dissmann Zusammenfassung Bisher im Kurs erarbeitete Konzepte(1): Umgang mit einfachen Datentypen Umgang mit Feldern Umgang mit Referenzen.
Zusammenfassung Vorwoche
PKJ 2005/1 Stefan Dissmann Klassenhierarchie Person Kunde Goldkunde Lieferant Object.
Packages Vortrag : Cornelia Hardt 23. November 1999.
1DVG3 - Paint Paint ein Zeichenprogramm. DVG3 - Paint 2 Paint – ein Zeichenprogramm.
DVG Einführung in Java1 Einführung in JAVA.
DVG Klassen und Objekte
DVG Einfache Klassen 1 Einfache Klassen. 2DVG Einfache KlassenStrukturen Beispiel: Personendaten bestehen aus String name String name.
Java in 9 Folien Besser: Online-Buch Go to Java 2.
Seite 1 Interface - Konzept Ein Interface führt einen neuen Datentyp ein: interface Frau {... } Das Interface enthält Deklarationen ( keine Definitionen.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
CuP - Java Elfte Vorlesung Montag, 11. November 2002.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
CuP - Java Eingabe über Tastatur, AudioClips, überschreiben, Quiz Montag, 18. November 2002.
Variablenkonzept Klassisch, in Java Basistyp
CuP - Java Neunte Vorlesung Entspricht Kapitel 4.2 und 5 des Skriptums
CuP - Java Vierte Vorlesung Entspricht ungefähr Kapitel 2.1 des Skriptums Montag, 14. Oktober 2002.
Programmierung von Agenten in Java: Implementierung einer Supply-Chain
Programmiervorkurs WS 2014/15 Methoden
Programmiervorkurs WS 2014/15 Instanzmethoden
3. Beschreibung von Abläufen durch Algorithmen 3.4 Zufall
Informatik I : Software höhere Programmiersprachen Java Klassen: hat Methoden (Funktionen) und Daten (Variablen) es kann mehrere Klassen geben nur eine.
Java-Kurs - 7. Übung Besprechung der Hausaufgabe Referenzvariablen
Alois Schütte Advanced System Programming 2 Interprozeßkommunikation  2.1 JVM Ablaufumgebung  2.2 Java Native Interface (JNI)  Verwendung von.
Java-Kurs - 4. Übung Hausaufgabe Weitere Kontrollstrukturen
Java-Kurs Übung Besprechung der Hausaufgabe
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer, Dr. Thomas H. Kolbe Einführung in die Programmierung mit Java 14. Vorlesung WS 2001/2002.
Programmierkurs JavaUE 4 Anweisungen und ProgrammeDietrich BolesSeite 1 Programmierkurs Java Dr. Dietrich Boles Teil Imperative Programmierung Unterrichtseinheit.
Eine Präsentation von Amed Fabrik und Alicia Sieg
 Präsentation transkript:

der Universität Oldenburg Programmierkurs Java Vorlesung im WS 1998/1999 am FB Informatik der Universität Oldenburg Vorlesung 13 Dietrich Boles

Gliederung von Vorlesung 13 Pakete Motivation Definition von Paketen Nutzung von Paketen Anmerkungen CLASSPATH JDK-Klassenbibliothek Beispiele Datenkapselung Definitionen Zugriffsrechte Übungen

Pakete / Motivation Im allgemeinen bestehen Programme aus vielen, vielen Klassen bestimmte Programmteile (Klassen) werden häufig gebraucht ( Speicher) im allgemeinen sogar in verschiedenen Anwendungen im allgemeinen sogar von unterschiedlichen Programmierern gesucht: Hilfsmittel, das es einem Programmierer erlaubt, seine Klassen übersichtlich und strukturiert abspeichern und verwalten zu können Hilfsmittel, das es einem Programmierer erlaubt, von ihm erstellte Klassen für mehrere Anwendungen nutzen zu können bzw. auch anderen Programmierern zur Verfügung stellen zu können Java:  Pakete (Packages) Klassenbibliothek: Sammlung von nützlichen, häufig gebrauchten Klassen, die (anderen) Programmierern zur Verfügung gestellt werden Java-Packages: Hilfsmittel zur Strukturierung von Klassenbibliotheken

Pakete / Definition von Paketen Schlüsselwort: package package-Anweisung: package <paketname>; Beispiel: Datei: GoBangBrett.java Datei: GoBangFigur.java Datei: GoBangSpieler.java Datei: GoBangRegeln.java Datei: GoBangSpielzug.java  Paket: gobang in jeder Datei muß als erste Anweisung (!!!!) die folgende package-Anweisung stehen: package gobang;

Pakete / Definition von Paketen Datei: GoBangBrett.java package gobang; public class GoBangBrett { ... } Datei: GoBangFigur.java public class GoBangFigur { Datei: GoBangSpieler.java package gobang; public class GoBangSpieler{ ... } Datei: GoBangRegeln.java public class GoBangRegeln {

Pakete / Definition von Paketen Anmerkungen: Der Paketname ist ein Java-Bezeichner Die Dateien/Klassen eines Paketes müssen sich alle in demselben Verzeichnis befinden! In einem Verzeichnis kann nur ein einziges Paket definiert werden! Der Name eines Verzeichnisses, in dem ein Paket definiert wird, muß gleich dem Namen des Paketes sein! Strukturierung von Paketen: Pakete lassen sich strukturieren (Punkt-Notation verwenden!) Beispiel: Strukturierung: Verzeichnisstruktur: Pakete - Spiele spiele package spiele; - Reversi spiele/reversi package spiele.reversi; - GoBang spiele/gobang package spiele.gobang; - Schach spiele/schach package spiele.schach;

Pakete / Nutzung von Paketen Schlüsselwort: import import-Anweisung: import <paket-qualifier>; es bestehen vier verschiedene Möglichkeiten, die Dateien/Klassen zu importieren bzw. auf die Elemente der Dateien/Klassen zuzugreifen: Import aller Dateien/Klassen des Paketes Import des Paketes Import einzelner Dateien/Klassen des Paketes kein expliziter Import Beispiel: Paket: java.util Datei/Klasse: Date Datei/Klasse: HashTable Datei/Klasse: Vector

Pakete / Nutzung von Paketen Import aller Dateien/Klassen des Paketes: import java.util.*; ... Date date = new Date(); Vector vector = new Vector(); Import des Paketes: import java.util; util.Date date = new util.Date(); util.Vector vector = new util.Vector();

Pakete / Nutzung von Paketen Import einzelner Dateien/Klassen des Paketes: import java.util.Date; ... Date date = new Date(); Vector vector = new Vector(); // Fehler! kein expliziter Import (Zugriff über vollständigen Namen) // kein import java.util.Date date = new java.util.Date(); java.util.Vector vector = new java.util.Vector();

Pakete / Nutzung von Paketen Namenskonflikte (Beispiel): package util;  class Vector package misc;  class Vector eigenes Programm: import util.*; import misc.*; ... Vector v = new Vector(); //Fehler: welcher Vector? // korrekt (Zugriff über vollständigen Namen): util.Vector v1 = new util.Vector(); misc.Vector v2 = new misc.Vector();

Pakete / Anmerkungen JDK-Paket: java.lang Datei/Klasse: System Datei/Klasse: Object Datei/Klasse: String Datei/Klasse: StringBuffer ...  import-Anweisung ist nicht notwendig (implizites import) Anonyme Pakete: Fehlt in Dateien eines Verzeichnisses die package-Anweisung, dann bilden die Dateien ein sogenanntes „anonymes Paket“ der Zugriff auf die Elemente eines anonymen Paketes ist ausschließlich auf Dateien im selben Verzeichnis (also Dateien/Klassen des anonymen Paketes selbst) beschränkt!

Pakete / CLASSPATH CLASSPATH: Variable der Betriebssystem-Shell setzen: csh: setenv CLASSPATH “.:/user/fb10/dibo/java“ bash: export CLASSPATH=.:/user/fb10/dibo/java Abfrage: echo $CLASSPATH wichtig: in den CLASSPATH müssen die Verzeichnisse (bzw. zip- oder jar-Dateien) aufgenommen werden, in denen der Java-Compiler und -Interpreter nach Paketen suchen soll Trennung mehrerer Verzeichnisse durch einen Doppelpunkt (:) der Punkt (.) ist wichtig für anonyme Pakete das Verzeichnis, in welchem sich die JDK-Klassenbibliothek befindet, muß nicht im CLASSPATH vorhanden sein

Pakete / CLASSPATH Beispiel: im Verzeichnis /user/fb10/dibo/java gibt es ein Paket namens dibo (Unterverzeichnis dibo), welches die Datei/Klasse Terminal enthält und ein Paket names dibo.gobang (Unterverzeichnis dibo/gobang), welches u.a. die Dateien/Klassen GoBangSpieler und GoBangSpielzug enthält ihr wollt die Pakete zur Implementierung einer Klasse MyGo nutzen: export CLASSPATH=.:/user/fb10/dibo/java Datei: MyGo.java (im Verzeichnis /user/kai/java) import dibo.*;  Zugriff auf Klasse Terminal import dibo.gobang.*;  Zugriff auf GoBangSpieler, ... public class MyGo { ... } Compilieren: javac MyGo.java Ausführen: java MyGo

Pakete / CLASSPATH Leicht modifiziertes Beispiel: dieselben Voraussetzungen, nur Ihr wollt ein eigenes Paket definieren: Datei: MyGo.java (im Verzeichnis /user/kai/java/mygobang) package mygobang; import dibo.*;  Zugriff auf Klasse Terminal import dibo.gobang.*;  Zugriff auf GoBangSpieler, ... public class MyGo { main: ... } export CLASSPATH=.:/user/fb10/dibo/java:/user/kai/java Compilieren: javac MyGo.java Ausführen: java mygobang.MyGo (von wo aus, ist egal!) Achtung: alle Verzeichnisse und class-Dateien müssen lesbar sein !

JDK-Klassenbibliothek Wird von Version zu Version erweitert (hier Version 1.1) enthält folgende Pakete: java.applet: Java-Applets (Applet, ...) java.awt: graphische Oberflächen (Fenster, GUI-Komponenten, Graphik, Layout-Manager, Container, ...) java.awt.datatransfer: Datentransfers zwischen Applikationen (Clipboards, ...) java.awt.event: Event-Handling (Maus-Events, Tastatur-Events, ...) java.awt.image: Bildverarbeitung (Farbe, Filter, ...) java.awt.peer: Plattform-spezifische GUI-Funktionalitäten java.beans: Java-Beans-API (Properties, Introspektion, ...) java.io: Ein-/Ausgabe (Streams, Dateien, ...)

JDK-Klassenbibliothek java.lang: Basis-Klassen (System, Object, Runtime, String, ...) java.lang.reflect: Java Reflection API (Introspektion, ...) java.math: Mathematik (Integer-, Floating-Point-Arithmetik, ...) java.net: Netzwerke (Sockets, URL, HTTP, ...) java.text: Internationale Programme (Texte, Datum, ...) java.util: Nützliche Klassen (Speicher (Vector, HashTable, BitSet, Stack, ...), Datum, Random, Scanner, ...) java.util.zip: Datenkompression

JDK-Klassenbibliothek / java.util.Date public class Date extends Object implements Serializable, Cloneable { public Date(); // aktuelle Zeit public Date(int year, int month, int date, int hrs, int min, int sec); public boolean after(Date when); // spaeter? public boolean equals(Object obj); public void toString(); public String toGMTString(); public int getMonth(); public void setMonth(int month); ... }

JDK-Klassenbibliothek / java.util.Date import java.util.Date; public class Datum { public static void main(String args) { Date datum = new Date(); System.out.println(datum); datum.setMonth(10); Datum d2; if (datum.after(d2 = new Date()) System.out.println(“sollte eigentlich ...“); else if (datum.equals(d2)) System.out.println(“gleich“); System.out.println(new Date().toGMTString()); } }

JDK-Klassenbibliothek / java.util.Random public class Random extends Object implements Serializable { public Random(long seed); // Pseudo-Zufall public Random(); // seed == aktuelle Zeit public void setSeed(long seed); public float nextFloat(); // [0..1] public int nextInt(); // [minint.. maxint] public double nextGaussian(); .... }

JDK-Klassenbibliothek / java.util.Random import java.util.Random; public class Wuerfel { Random zufall; public Wuerfel() { this.zufall = new Random(); } public int wuerfeln() { int wert = this.zufall.nextInt(); if (wert < 0) wert = -wert; return (wert%6) + 1; }

JDK-Klassenbibliothek / java.util.Vector public class Vector extends Object implements Cloneable, Serializable { protected Object[] elementData; protected int elementCount; public Vector(int init_size); public void addElement(Object obj); public final boolean contains(Object obj); public final Object elementAt(int index); public final void insertElementAt(Object o,int i); public final void removeElement(Object obj); public final int size(); public final String toString(); ... }

JDK-Klassenbibliothek / java.util.Stack public class Stack extends Vector { public Stack(); public boolean empty(); public Object peek(); public Object pop(); public Object push(Object obj); ... }

JDK-Klassenbibliothek / java.util.HashTable Protokoll: public class HashTable extends Dictionary implements Cloneable, Serializable { public HashTable() public void put(Object key, Object value); public Object get(Object key); public boolean containsKey(Object key); public Object remove(Object key); ... } HashTabellen sind sehr effizient suchbare Speicher!

JDK-Klassenbibliothek / java.util.HashTable Nutzung: import java.util.HashTable; class Mitarbeiter { String name; int alter; // name + alter eindeutig! float gehalt; public Mitarbeiter(String n, int a, float g) { name = n; alter = a; gehalt = g; }

JDK-Klassenbibliothek / java.util.HashTable class MitarbeiterKey { String name; int alter; public MitarbeiterKey(String n, int a) { name = n; alter = a; } public int hashCode() { // wird von Object geerbt int hash = 0; for (int i=0; i<name.length(); i++) hash += name.charAt(i); return hash + alter; public boolean equals(Object obj) { MitarbeiterKey key = (MitarbeiterKey)obj; return name.equals(key.name) && (alter == key.alter); } }

JDK-Klassenbibliothek / java.util.HashTable public class Verwaltung { public static void main(String[] args) { Verwaltung v = new Verwaltung(); v.insertAlleMitarbeiter(); ... Mitarbeiter kurt = v.getMitarbeiter(“kurt“, 30); System.out.println(kurt.gehalt); } HashTable elems; public Verwaltung() {elems = new HashTable();} public void insertAlleMitarbeiter() { Mitarbeiter m = new Mitarbeiter(“kurt“,30,4444.0); elems.put(new MitarbeiterKey(m.name,m.alter), m); public Mitarbeiter getMitarbeiter(String n, int a) { return elems.get(new MitarbeiterKey(n, a)); } }

JDK-Klassenbibliothek / java.util.HashTable Implementierung: class Elem { Object key; Object obj; public Elem(Object k, Object o) { key = k; obj = o; } } public class HashTable { Vector[] table; public HashTable() { table = new Vector[1000]; for (int i=0; i<1000; i++) table[i]=new Vector(); } public void put(Object key, Object value) { int index = key.hashCode()%table.length; table[index].addElement(new Elem(key, value));

JDK-Klassenbibliothek / java.util.HashTable public Object get(Object key) { int index = key.hashCode()%table.length; Enumeration enum = table[index].elements(); while (enum.hasMoreElements()) { Elem elem = (Elem)(enum.nextElement()); if (elem.key.equals(key)) return elem.obj; } return null; // nicht vorhanden public Object remove(Object key) { int ind = key.hashCode()%table.length; for (int i=0; i<table[ind].size(); i++) { Elem elem = (Elem)(table[ind].elementAt(i)); if (elem.key.equals(key)) { table[ind].removeElementAt(i); } } return null;

Datenkapselung Motivation: Def.: Datenkapselung bessere Überschaubarkeit und Wartbarkeit von Programmen weniger mögliche Fehlerquellen Def.: Datenkapselung Datenkapselung bezeichnet den Schutz von Daten (Attributen) vor unmittelbarem Zugriff. Die Daten (Attribute) sind nur mittels der ihnen zugeordneten Operationen (Methoden) zugreifbar. Def.: Information Hiding Bewußtes Verbergen von internen Informationen wie Implementierungsdetails nach außen. Es werden ausschließlich genau definierte Schnittstellen (Protokolle) nach außen sichtbar gemacht. Def.: Datenabstraktion Prinzip, nach dem nur die auf ein Objekt anwendbaren Operationen von außen sichtbar und zugreifbar sind (nicht die Daten und die Implementierung) (Datenabstraktion = Datenkapselung + Information Hiding)

Datenkapselung Def.: Abstrakter Datentyp (ADT) Zusammenfassung einer Menge von Daten (Attributen) mit den auf ihnen ausführbaren Operationen (Methoden). Das Konzept des ADT erlaubt die Spezifikation der relevanten Eigenschaften von Datenstrukturen, ohne daß Realisierungsaspekte sichtbar werden. Realisierung: Modula-2: Definition- und Implementation-Module OO-Sprachen (generell): Klassen, Pakete und Zugriffsrechte C++: Header- und Implementation-Dateien (Klassendefinition und Implementierung der Methoden in getrennten Dateien) Java: leider keine strukturelle Unterstützung (Methoden-Implementierung innerhalb der Klassendefinition) sehr feingranulare Unterstützung durch Zugriffsrechte

Zugriffsrechte auf Klassen In Java existieren zwei verschiedene Möglichkeiten, Zugriffsrechte auf Klassen zu definieren: public <default> (Zugriffsschlüsselwort fehlt!) public-Klassen sind von überall her zugreifbar/nutzbar <default>-Klassen sind nur in dem Paket zugreifbar/nutzbar, in dem sie definiert werden in einer Datei können mehrere Klassen definiert werden, aber nur eine darf eine public-Klasse sein! Richtlinien: will man öffentlich zugängliche Klassen definieren, sollte man sie als public deklarieren Hilfsklassen sollten immer default deklariert werden

Zugriffsrechte auf Klassen Beispiel (Datei Vector.java): public class Vector { Object[] elements; int size; public Vector(int size) { ... } ... public Enumeration elements() { return new VectorEnumerator(this); } class VectorEnumerator implements Enumeration {

Zugriffsrechte auf Attribute und Methoden In Java existieren vier verschiedene Möglichkeiten, Zugriffsrechte auf Attribute und Methoden zu definieren (in absteigender Reihenfolge): public protected <default> (Zugriffsschlüsselwort fehlt!) private public-Attribute/Methoden sind von überall her zugreifbar protected-Attribute/Methoden sind nur zugreifbar in allen Klassen desselben Paketes sowie in abgeleiteten Klassen (auch anderer Pakete) <default>-Attribute/Methoden sind zugreifbar in allen Klassen desselben Paketes private-Attribute/Methoden sind nur zugreifbar in derselben Klasse

Zugriffsrechte auf Attribute und Methoden Beispiel (Datei Vector.java): public class Vector { protected Object[] elements; protected int size; public Vector(int size) { ... } ... public Enumeration elements() { return new VectorEnumerator(this); } class VectorEnumerator implements Enumeration { private Vector vec; VectorEnumerator(Vector v) {this.vec = v;}

Zugriffsrechte auf Attribute und Methoden Richtlinien (Attribute): Definieren Sie Attribute möglichst niemals als public ( Datenkapselung) Definieren Sie Attribute, die lediglich innerhalb der Klassenimplementierung benötigt werden, als private oder <default> Definieren Sie Attribute, auf die evtl. jemand zugreifen muß, wenn er eine Klasse von der Klasse ableitet, immer als protected Konstanten werden im allgemeinen als public definiert (kann man eh nicht manipulieren) Richtlinien / Anmerkungen (Methoden): Definieren Sie nur die Methoden als public, die Sie anderen zur Verfügung stellen wollen bei in abgeleiteten Klassen überschriebenen Methoden dürfen die Rechte ausschließlich erweitert werden (private  <default>  protected  public)

Zugriffsrechte auf Attribute und Methoden Übung: wo liefert der Compiler Fehlermeldungen? Verzeichnis: misc Datei: X.java public class X { private int i1; int i2; protected int i3; public int i4; void f() { this.i1 = 3; this.i2 = 4; this.i3 = 5; this.i4 = this.i1; } } Verzeichnis: misc Datei: Y.java public class Y { int i1; public Y(X obj) { obj.i1 = 3; obj.i2 = 4; obj.i3 = 5; obj.i4 = this.i1; obj.f(); } }

Zugriffsrechte auf Attribute und Methoden Übung: wo liefert der Compiler Fehlermeldungen? Verzeichnis: misc Datei: X.java package misc; public class X { private int i1; int i2; protected int i3; public int i4; void f() { this.i1 = 3; this.i2 = 4; this.i3 = 5; this.i4 = this.i1; } } Verzeichnis: util Datei: Y.java package util; import misc.*; public class Y { int i1; public Y(X obj) { obj.i1 = 3; obj.i2 = 4; obj.i3 = 5; obj.i4 = this.i1; obj.f(); } }

Zugriffsrechte auf Attribute und Methoden Übung: wo liefert der Compiler Fehlermeldungen? Verzeichnis: misc Datei: X.java package misc; public class X { private int i1; int i2; protected int i3; public int i4; void f() { this.i1 = 3; this.i2 = 4; this.i3 = 5; this.i4 = this.i1; } } Verzeichnis: util Datei: Y.java package util; import misc.*; public class Y extends X { int i1; public Y(X obj) { obj.i1 = 3; obj.i2 = 4; obj.i3 = 5; obj.i4 = this.i1; obj.f(); } }