Jak stworzyś synonim typu

0

Siema,

mam małe pytanie, chciałbym stworzyć synonim klasy np. Float lub Integer nie mylić z typami podstawowymi tak, abym mógł w kodzie użyć zamiast Float np. Analog.

class Device<T> {
 private T state;

 public Device(T val) {
  state = val;
 }
 public void setState(T val) {
  state = val;
 }

 public T getState() {
  return state;
 }
}

Nie chcĘ używać pakietu corba, chciałbym zachować prostotę używanie klas opakowań.

0

A możesz rozszerzyć kwestię o to jaki cel chcesz w ten sposób osiągnąć?
Bo zrobienie opakowania, to raczej nie jest jakiś problem i stosuje się go często kiedy nie można po jakiejś klasie dziedziczyć, a potrzebna jest jej funkcjonalność.
Tyle, że semantyka opakowania musi zależeć od klasy opakowywanej, żeby było to jakoś użyteczne. Inaczej mówiąc opakować możesz teoretycznie dowolny typ, ale wykorzystasz jego cechy pod warunkiem, że je znasz lub wiesz czemu służą.

0

Chciałbym po prostu stworzyć coś typu frameworka, ale zrozumiałego dla programisty.
Tworząc Device<Float>, a tworząc Device<Analog> co jest bardziej zrozumiałe?

0

A co ten framework miałby robić tak w przybliżeniu? Bo w końcu powinien to być kod użyteczny i uniwersalny dla jakichś zastosowań. Sam szkielet z kodem, który jedynie deleguje jest bezwartościowy i zasadniczo tylko spowalnia działanie właściwego kodu. W każdym razie jak nie poważyłbym się na tak ogólny szablon. Frameworka warto tworzyć gdy conajmniej kilka razy musiałeś już powtarzać jakiś naprawdę niebanalny i przydatny kod. W innym wypadku jest to przedwczesna i bardzo wątpliwa optymalizacja.
A robienie kodu "dla programistów", to szczególnie ciężka sprawa i trzeba mieć naprawdę mocne kwalifikacje, aby w ogóle próbować się za coś takiego zabierać.

0
KGawlinski napisał(a)

mam małe pytanie, chciałbym stworzyć synonim klasy np. Float lub Integer..

nie da sie.. typedef'y "byly" w C/CPP, tutaj nima. pozostaje SED s/Analog/Float/g :)

0

Ok, może inaczej, framework to zbyt szerokie pojęcie, dla mojego problemu. quetzalcoalt zczaił baze szukam dokładnie czegoś takiego jak typedef w C. Chodzi mi po prostu o to, że czytając kod widząc linie new Device<Analog> Od razu wiadomo o co chodzi. To ma po prostu służyć lepszej czytelności kodu zarówno dla mnie, jak zechce za jakiś czas zajrzeć do tego programu, jak i dla innych.

0

W javie odpowiednikiem typedef z C (tylko o wiele szerszym) jest mechanizm klas.
Jeżeli chcesz coś takiego uzyskać, żeby posługiwać się nazwą Analog, to po prostu definiuje się klasę Analog, która może reprezentować zarówno float jak i dowolny inny typ. Można w tym celu jawnie zdefiniować taką klasę (oraz jej odmiany przez delegację, albo dziedziczenie) lub stworzyć z niej klasę szablonową. Tu przykład klasy abstrakcyjnej:

/** zawiera jakiś użyteczny kod charakterystyczny dla wszystkich analogów */
abstract class Analog
{
//...
}
//...
public void device(Analog argument)
{
//...
}

//...
/** szczegółowa wersja konkretna Analogu */
class KonkretnyAnalog1 extends Analog
{
//...
}
//...
/** szczegółowa wersja konkretna Analogu */
class KonkretnyAnalog2 extends Analog
{
//...
}

//...
Analog analog = new KonkretnyAnalog1();
Analog innyAnalog = new KonkretnyAnalog2();

//użycie
device(analog);
device (innyAnalog);

Równie dobrze Analog mógłby być interfejsem, jak i klasa konkretną, która nic lub niewiele robi.

Jedynym sposobem uzyskania prostego aliasingu klas w javie jest dziedziczenie bez dodawania jakichkolwiek nowych właściwości dla klasy potomnej. Tyle, że jest to zbędne mnożenie bytów. Twórcy języka zlikwidowali tę możliwość dla typów opakowujących typy proste dając im po prostu modyfikator final.

0

Ja bym stworzył klasę Analog o sygnaturze :

public class Analog extends Float {

 public Analog(double cos) {
    super(cos)
 }

 //analogicznie dla pozostalych konstruktorów


}

Taka klasa będzie dziedziczyła wszelkie nie-prywatne pola i metody Float'a, a nazwa będzie inna.
Problemem może być to, że autoboxing i jemu podobne triki nie będą raczej działać.

0
kamykadze napisał(a)

Ja bym stworzył klasę Analog o sygnaturze :

public class Analog extends Float {...}

Taka klasa będzie dziedziczyła wszelkie nie-prywatne pola i metody Float'a, a nazwa będzie inna.

Nie ma szans. --> "Cannot inherit from final java.lang.Float"
Już pomijam fakt, że każda klasa dziedziczy po przodku wszystkie pola i metody. Tyle, że część z nich (prywatne i pakietowe) nie jest dostępna dla klasy potomnej.

0

Kamykadze właśnie dlatego szukam innego rozwiązania bo twój sposób nie działa.
olamagato - czyli, konkretnie nie da rady utworzyć aliasu dla klasy. Twórcy java uznali to za zbędne. Twój sposób z dziedziczeniem jest ok, ale tracę funkcjonalność posługiwania się klasą Analog tak jak np. klasą Float.

Myślę, że po prostu używając prostych technik nie można tego zrobić, a stosowanie technik, które redukują prędkość działania kodu było by po prostu głupie - o czym zresztą olamagato wspomniał na początku postu.

Dzięki, za chęci rozwiązania problemu. Narqa

0

Jest jeszcze sposób na przeskoczenie tego jeżeli baaardzo chcesz tak to rozwiązać. Po musisz zrobić własne opakowania dla typów nieobiektowych takich jak float. Możesz przy tym skorzystać ze źródeł klas opakowujących produkcji Suna. Być może najprościej jest po prostu skopiować źródło tych klas i usunąć z nich modyfikator final, no i oczywiście zmienić nazwy. Być może będzie nawet działać autoboxing, ale głowy nie dam bo nie sprawdzałem.

0

a moze zrobic tak:

abstract class Device<T>;
class AnalogDevice extends Device<Float>;

i w kodzie uzywasz AnanlogDevice, co jest czytalne, a poza tym masz jak to nazwałeś funkcjonalność posługiwania się klasą Float

0

hurikhan próbowałem już tego, ale pojawił się jakiś problem w momencie kiedy klasa abstrakcyjna zawierała konstruktor z parametrami. Musiałem powielić ten konstruktor w każdej klasie dziedziczącej od klasy abstrakcyjnej, a potem w klasie, w której chciałem wykorzystać <AnalogDevice> był jakiś zgrzyt.
Kod mam chyba jeszcze na kompie w domu. Jak znajde to pokaże, jak nie to spróbuje to napisać jeszcze raz.

Olamagato ciekawy pomysł, spróbuje to zrobić, ale wątpie, żeby działał autoboxing.
I mam pytanie, biblioteki java'y są open source, ale czy mogę wykorzystywać je w taki sposób znaczy modyfikując oryginalny kod?

0

Źródła możesz użyć jako przykładu. Problem w tym, że definicja np. Float odwołuje się już do klas zastrzeżonych przez Suna jako biblioteki prywatne. I być może w tym będzie zgrzyt.

0

Niewiem o co hodzi, ale jak odpaliłem kod jeszcze raz to zadziałał;)

import java.util.*;

public class Kolekcje {
	public static void main(String[] args) {
		Device<Analog> aDevice = new Device<Analog>(new Analog(0.0f));
		Device<Digital> dDevice = new Device<Digital>(new Digital(true));
		
		aDevice.setState(1.0f);
		dDevice.setState(false);
		
		System.out.println(aDevice.getState().getClass());
		System.out.println(dDevice.getState().getClass());
	}
} 

abstract class DeviceType<T> {
	T state;
	
	public DeviceType(T val) {
		state = val;
	}
	
	public T getState() {
		return state;
	}
	
	public void setState(T val) {
		state = val;
	}
}

class Analog extends DeviceType<Float> {
	public Analog(Float val) {
		super(val);
	}
}
class Digital extends DeviceType<Boolean> {
	public Digital(Boolean val) {
		super(val);
	}
}

class Device<T extends DeviceType> extends DeviceType {
	public Device(T val) {
		super(val);
	}
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1