use strict; use warnings; package Table; sub MakeTypeA { my ($class, %params) = @_; return $class->TypeA::new(%params); } sub MakeTypeB { my ($class, %params) = @_; return $class->TypeB::new(%params); } sub ShowType { my ($self) = @_; print "$self->{type}\n"; } package TypeA; push @TypeA::ISA, 'Table'; sub new { my ($class, %params) = @_; return bless {type => 'TypeA', %params}, $class; } sub foo { print "TypeA::foo\n"; } package TypeB; push @TypeB::ISA, 'Table'; sub new { my ($class, %params) = @_; return bless {type => 'TypeB', %params}, $class; } sub baa { print "TypeA::baa\n"; } package MiddleMan; push @MiddleMan::ISA, 'Table'; sub ShowType { my ($self) = @_; print 'MiddleMan, '; $self->SUPER::ShowType(); } sub ShowClass { my ($self) = @_; print ref $self, "\n"; } package MyClass1; push @MyClass1::ISA, 'MiddleMan'; package MyClass2; push @MyClass2::ISA, 'MiddleMan'; package main; my $obj1 = MyClass1->MakeTypeA(); my $obj2a = MyClass2->MakeTypeA(); my $obj2b = MyClass2->MakeTypeB(); $obj1->ShowType(); $obj1->ShowClass(); $obj2a->ShowType(); $obj2a->ShowClass(); $obj2b->ShowType(); $obj2b->ShowClass();