Inheritance - CIS 1068 Program Design and Abstraction - PowerPoint PPT Presentation

1 / 79
About This Presentation
Title:

Inheritance - CIS 1068 Program Design and Abstraction

Description:

Inheritance - CIS 1068 Program Design and Abstraction Zhen Jiang CIS Dept. Temple University 1050 Wachman Hall, Main Campus Email: zhen.jiang_at_temple.edu * * – PowerPoint PPT presentation

Number of Views:157
Avg rating:3.0/5.0
Slides: 80
Provided by: PCU93
Learn more at: https://cis.temple.edu
Category:

less

Transcript and Presenter's Notes

Title: Inheritance - CIS 1068 Program Design and Abstraction


1
Inheritance - CIS 1068 Program Design and
Abstraction
  • Zhen Jiang
  • CIS Dept.
  • Temple University
  • 1050 Wachman Hall, Main Campus
  • Email zhen.jiang_at_temple.edu

2
Table of Contents
  • Introduction to inheritance
  • Inheritance
  • Syntax
  • More!
  • Overridding
  • OOP (object-oriented programming)
  • Polymorphism
  • Modifiers
  • Abstract class and interfaces
  • GUI

3
Introduction
  • Write an Employee class with methods that return
    values for the following properties of employees
    at a particular company
  • Work week 40 hours
  • Annual salary 40,000
  • Paid time off 2 weeks
  • Leave of absence form Yellow form

4
  • // A class to represent employees
  • public class Employee
  • public int getHours()
  • return 40 // works 40 hours /
    week
  • public double getSalary()
  • return 40000.0 // 40,000.00 / year
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation
  • public String getVacationForm()
  • return "yellow" // use the yellow
    form

5
  • Write a Secretary class with methods that return
    values for the following properties of
    secretaries at a particular company
  • Work week 40 hours
  • Annual salary 40,000
  • Paid time off 2 weeks
  • Leave of absence form Yellow form
  • Add a method takeDictation that takes a string as
    a parameter and prints out the string prefixed by
    "Taking dictation of text ".

6
  • // A class to represent secretaries
  • public class Secretary
  • public int getHours()
  • return 40 // works 40 hours /
    week
  • public double getSalary()
  • return 40000.0 // 40,000.00 / year
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation
  • public String getVacationForm()
  • return "yellow" // use the yellow
    form
  • public void takeDictation(String text)

7
  • // A class to represent employees
  • public class Employee
  • public int getHours()
  • return 40
  • public double getSalary()
  • return 40000.0
  • public int getVacationDays()
  • return 10
  • public String getVacationForm()
  • return "yellow"
  • // A class to represent secretaries
  • public class Secretary
  • public int getHours()
  • return 40
  • public double getSalary()
  • return 40000.0
  • public int getVacationDays()
  • return 10
  • public String getVacationForm()
  • return "yellow"
  • public void takeDictation(String text)

Compare these two!
8
Inheritance Is-a relationship
  • is-a relationship A hierarchical connection
    where one category can be treated as a
    specialized version of another.
  • Examples
  • Every secretary is an employee.
  • Every square is a rectangle.
  • Every dog is a mammal.

9
  • code reuse The practice of writing program code
    once and using it in many contexts.
  • We'd like to be able to say the following
  • // A class to represent secretaries
  • public class Secretary
  • ltcopy all the contents from Employee classgt
  • public void takeDictation(String text)
  • System.out.println("Taking dictation of
    text "
  • text)
  • That way we would be reusing the Employee code.

10
  • inheritance A way to specify a relationship
    between two classes where one class inherits the
    state and behavior of another.
  • The child class (also called subclass) inherits
    from the parent class (also called superclass).
  • The subclass receives a copy of every field and
    method from the superclass.

11
Syntax
  • Creating a subclass, general syntax
  • public class ltsubclass namegt extends ltsuperclass
    namegt
  • Example
  • public class Secretary extends Employee
  • ....
  • By extending Employee, each Secretary object
    automatically has a getHours, getSalary,
    getVacationDays, and getVacationForm method.

12
  • Improved Secretary class
  • // A class to represent secretaries
  • public class Secretary extends Employee
  • public void takeDictation(String text)
  • System.out.println("Taking dictation of
    text "
  • text)

13
Writing even more classes
  • Write a Marketer class that represents marketers
    who have the same properties as general
    employees, but instead of making only a paltry
    40,000, marketers make 50,000!
  • Can we still leverage the Employee class or do we
    have to re-write everything, because one method
    (getSalary) is different?
  • If only Marketer could write a new version of the
    getSalary method, but inherit everything else

14
Overriding methods
  • override To write a new version of a method in a
    subclass to replace the superclass's version.
  • To override a superclass method, just write a new
    version of it in the subclass. This will replace
    the inherited version.

15
Marketer class
  • // A class to represent marketers
  • public class Marketer extends Employee
  • public void advertise()
  • System.out.println("Act now while
    supplies last!")
  • public double getSalary()
  • return 50000.0 // 50,000.00 / year

16
OOP Based in reality or too convenient?
  • At many companies, all new employees attend a
    common orientation to learn general rules (e.g.,
    what forms to fill out when).
  • Each person receives a big manual of these rules.
  • Each employee also attends a subdivision-specific
    orientation to learn rules specific to their
    subdivision (e.g., marketing department).
  • Everyone receives a smaller manual of these rules.

17
  • The smaller manual adds some rules and also
    changes (read overrides) some rules from the
    large manual (e.g., "use the pink form instead of
    the yellow form")?

18
  • Why not just have a 22-page manual for lawyers,
    21-page manual for secretaries, 23-page manual
    for marketers, etc?

19
  • maintenance If a common rule changes, only the
    common manual needs to be updated.

20
  • The 20 page manual manner is useful to be able to
    specify general rules that will apply to many
    groups.
  • Locality
  • A person can look at the manual for lawyers and
    quickly discover all rules that are specific to
    lawyers.
  • It is also useful to specify a smaller set of
    rules for such a particular group, including
    being able to replace rules from the overall set
    (overriding, e.g., "use the pink form instead of
    the yellow form").

21
//base classpublic class PubA public int x
1 public void setX() x2 public int
getX() return x
//attribute method inheritancepublic class
PubB extends PubA public void setX()x3
overriding
2 3
PubA a new PubA() PubB b new PubB()
a.setX() b.setX() System.out.println(a.getX())
System.out.println(b.getX())
22
Why inheritance?
  • Need for Jbutton, FlowLayout, JTextField, etc
  • http//www.cis.temple.edu/jiang/Extend_action.pdf
  • Need for a customized response from the computer
    for all GUI actions
  • http//www.cis.temple.edu/jiang/MultiEventSource.
    pdf

23
Constructor for superclass
24
  • public class Employee
  • private double salary
  • public Employee(double initialSalary)
  • salary initialSalary
  • public int getHours()
  • return 40 // 40 hours per week
  • public double getSalary()
  • return salary
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation
  • public String getVacationForm()
  • return "yellow" // use the yellow
    form

25
  • Use the super() method to call the superclasss
    constructor
  • public class Marketer extends Employee
  • // inherits double salary
  • public Marketer(double initialSalary)
  • //construct superclass
  • super(initialSalary)
  • - For every constructor of a subclass, the call
    to super() must be the first statement in the
    subclasss constructor.
  • - Make sure to give the same number of arguments
    as there are parameters in the definition of the
    superclasss constructor.

26
  • Question If a method is declared private, does
    a subclass inherit it?
  • Actually, yes. Subclasses inherit everything
    that they dont override.
  • If a method is declared private, can a subclass
    call it?
  • NO! Only code inside the same class can call a
    private method.
  • What if you want a subclass to be able to use it?
  • Use the protected access level

27
  • public class Employee
  • private double salary 40000.00
  • public int getHours()
  • return 40 // works 40 hours /
    week
  • public double getSalary()
  • return salary
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation
  • public String getVacationForm()
  • return "yellow" // use the yellow
    form

28
  • Subclasses cannot see salary directly!
  • public class CEO extends Employee
  • public void giveMyselfRaise()
  • salary 1000000.00 // Compile-time
    Error!
  • public static void main(String args)
  • CEO c new CEO()
  • // This is fine, no error here
  • // Access to salary field is indirect
  • // Were accessing the public getSalary()
    method
  • System.out.println(My salary is
    c.getSalary())

29
  • public class Employee
  • protected double salary 40000.00
  • public int getHours()
  • return 40 // works 40 hours /
    week
  • public double getSalary()
  • return salary
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation
  • public String getVacationForm()
  • return "yellow" // use the yellow
    form

30
  • Subclasses can see protected variables and
    methods just fine.
  • public class CEO extends Employee
  • public void giveMyselfRaise()
  • salary 1000000.00 // No longer an
    error
  • public static void main(String args)
  • CEO c new CEO()
  • // This is fine, no error here
  • // Access to salary field is indirect
  • // Were accessing the public getSalary()
    method
  • System.out.println(My salary is
    c.getSalary())

31
What would happen if ....
  • public class Employee
  • private double salary 40000.00
  • public int getHours()
  • return 40 // works 40 hours /
    week
  • public double getSalary()
  • return salary
  • public void addToSalary(double raise)
  • salary raise
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation

32
  • public class CEO extends Employee
  • public void giveMyselfRaise()
  • addToSalary(1000000.00)
  • CEO still has its own copy of the salary field,
    and this code will change the value of it
    appropriately.
  • The fact that salary is private simply means that
    CEO can't access it directly. It can still call
    public (or protected) superclass methods that can
    access it.

33
//base class public class ProA private int x
1 protected void setX(int a) xa
protected int getX() return x
//sub class public class ProB extends ProA
public int getB() setX(2) // your next step
is to return x // but return x does not work
// due to the private modifier, so return
getX()
1 2
ProA a new ProA() ProB b new ProB()
System.out.println(a.getX())
System.out.println(b.getB())
34
Polymorphism
  • A reference variable of type T can refer to an
    object of any subclass of T.
  • Employee Laura new Lawyer()
  • Employee Mark new Marketer()
  • polymorphism The ability for the same code to be
    used with several different types of objects and
    behave differently depending on the type of
    object used.

35
  • Employee Laura new Lawyer()
  • System.out.println(Laura.getSalary()) //
    40000.0
  • System.out.println(Laura.getVacationForm()) //
    "pink"
  • You can call any method from Employee on the
    person variable, but not any method specific to
    Lawyer (such as sue).
  • Once a method is called on that object, it
    behaves in its normal, overridden way (as a
    Lawyer, not as a normal Employee).

36
public class Marketer extends Employee
public void advertise()
System.out.println("Act now while supplies
last!") public double getSalary()
return 50000.0 // 50,000.00 /
year
public class Secretary extends Employee
public void takeDictation(String text)
System.out.println("Taking dictation of text "
text)
  • public class EmployeeMain
  • public static void main(String args)
  • Secretary laura new Secretary()
  • Marketer mark new Marketer()
  • printInfo(laura)
  • printInfo(mark)
  • public static void printInfo(Employee empl)
  • System.out.println("salary "
    empl.getSalary())
  • System.out.println("days "
    empl.getVacationDays())
  • System.out.println("form "
    empl.getVacationForm())
  • System.out.println()
  • Output
  • salary 40000.0
  • vacation days 10

Polymorphism and parameters
37
  • public class EmployeeMain2
  • public static void main(String args)
  • Employee employees new Secretary(),
    new Marketer()
  • for (int i 0 i lt employees.length
    i)
  • System.out.println("salary "
    employeesi.getSalary())
  • System.out.println("vacation days "
  • employeesi.getVac
    ationDays())
  • System.out.println()
  • Output
  • salary 40000.0
  • vacation days 10
  • salary 50000.0
  • vacation days 10

Polymorphism and arrays
38
Exercises
  • public class Foo
  • public void method1()
  • System.out.println("foo 1")
  • public void method2()
  • System.out.println("foo 2")
  • public String toString()
  • return "foo"
  • public class Bar extends Foo
  • public void method2()
  • public class Baz extends Foo
  • public void method1()
  • System.out.println("baz 1")
  • public String toString()
  • return "baz"
  • public class Mumble extends Baz
  • public void method2()
  • System.out.println("mumble 2")
  • Assume that the following four classes have been
    declared

39
  • What would be the output of the following client
    code?
  • Foo pity new Baz(), new Bar(),
  • new Mumble(), new Foo()
  • for (int i 0 i lt pity.length i)
  • System.out.println(pityi)
  • pityi.method1()
  • pityi.method2()
  • System.out.println()

40
(No Transcript)
41
  • The code produces the following output
  • baz
  • baz 1
  • foo 2
  • foo
  • foo 1
  • bar 2
  • baz
  • baz 1
  • mumble 2
  • foo
  • foo 1
  • foo 2

42
  • Kind of override under the standard of superclass!

43
Variable ShadowingSomething to avoid!!
  • Polymorphism applies to methods in Java
  • But not to fields!
  • public class A
  • int x 1
  • int method() return 1
  • public class B extends A
  • int x 2
  • int method() return 2

A a1 new A() A a2 new B() System.out.printl
n(a1.method()) // prints 1 System.out.println(a2.
method()) // prints 2 System.out.println(a1.x)
// prints 1 System.out.println(a2.x) // prints
1 still! // Not like method, which prefers to
its own.
44
  • Variable Shadowing
  • When a class extends another class and defines a
    field with the same name, each object of the
    subclass contains two fields with that name.
  • The supclasss version of the field is said to
    shadow the subclasss version, making the
    subclasss version invisible within that class.
  • This is called variable shadowing.

45
public class A protected int x 1 protected
void setX(int a) xa protected int getX()
return x   public class B extends A
protected int x 3 public int getX() return
x public int getB() return x
1 3 3 1 3
A a new A() B b new B()
System.out.println(a.getX())
System.out.println(b.getX())
System.out.println(b.getB())
System.out.println(a.x) System.out.println(b.x)

The difference is shadow!
A a new A() A b new B()
System.out.println(a.getX())
System.out.println(b.getX())
//System.out.println(b.getB())
System.out.println(a.x) System.out.println(b.x)

1 3 1 1
46
  • http//www.cis.temple.edu/jiang/1068_modifier_inh
    eritance.pdf

47
  • Exercises
  • Slide 39
  • PolymorphismDemo
  • www.cis.temple.edu/jiang/PolymorphismDemo.pdf
  • www.cis.temple.edu/jiang/Person.pdf
  • www.cis.temple.edu/jiang/Student.pdf
  • www.cis.temple.edu/jiang/Undergradaute.pdf

48
Modifiers
  • Public
  • A class, method, constructor, interface etc
    declared public can be accessed from any other
    class. Therefore fields, methods, blocks declared
    inside a public class can be accessed from any
    class belonging to the Java Universe.
  • Because of class inheritance, all public methods
    and variables of a class are inherited by its
    subclasses.

49
  • Private
  • Methods, Variables and Constructors that are
    declared private can only be accessed within the
    declared class itself.
  • Private access modifier is the most restrictive
    access level. Class and interfaces cannot be
    private.
  • Variables that are declared private can be
    accessed outside the class only if public
    accessor methods are present in the class.

50
  • Protected
  • Variables, methods and constructors which are
    declared protected in a superclass can be
    accessed only by the subclasses.
  • Protected access gives the subclass a chance to
    use the helper method or variable, while
    preventing a nonrelated class from trying to use
    it.

51
  • Default (like public)
  • Default access modifier means we do not
    explicitly declare an access modifier for a
    class, field, method etc.
  • A variable or method declared without any access
    control modifier is available to any other class
    in the same package.
  • For example
  • public class Logger
  • String format
  • String getFormat() return this.format
  • public void setFormat(String f) format
    f

52
Abstract and Interfaces
  • What have you learnt from the above exercises on
    extends?
  • Is it good to block the use of subclass method
    that is not declared in super class?
  • Good, because methods can be in template. In the
    security control, no leakage!
  • Is it good to have the direct access of
    attribute?
  • Better not, if it is not in your control. See how
    complicate it is in the variable shadowing.

53
  • Suppose weve defined an Employee class, and we
    dont want someone to come along and muck it up
  • E.g., we dont want a CEO subclass that gives
    itself a raise
  • The final keyword indicates that some definition
    (of a class, method, or field) cannot be changed
    or overridden by a subclass.

54
final Example
  • // A class to represent employees
  • public class Employee
  • public int getHours()
  • return 40 // works 40 hours /
    week
  • public final double getSalary()
  • return 40000.0 // 40,000.00 / year
  • public int getVacationDays()
  • return 10 // 2 weeks' paid
    vacation
  • public String getVacationForm()
  • return "yellow" // use the yellow
    form
  • No subclass is allowed to change the definition
    of getSalary()!

55
final fields, methods, and classes
  • The final keyword can be applied to fields (as
    weve seen before)
  • // no code may change the value of salary,
  • //including a subclasss code
  • public final double salary 40000.0
  • Or to methods
  • // subclasses cannot override the getSalary
    method
  • public final double getSalary() return salary
  • Or even to classes
  • // the Employee class cannot be extended
  • // It cant have any subclasses at all!
  • public final class Employee ...

56
Opposite of final
  • The final keyword prevents subclasses from
    changing (overriding) code
  • Sometimes, you want to do the opposite
  • Force another programmer or piece of code
  • to finish parts of a class.

57
Example Employee salary
  • Lets say you want every subclass of Employee to
    have a salary, but you want the subclass to
    decide what the salary should be.
  • We can define an abstract getSalary() method
  • public abstract double getSalary()
  • Note no method definition!
  • Abstract method declarations dont provide
    definitions, just signatures.
  • They are there to force subclasses to provide the
    definitions.

58
Abstract Rules (1)
  • If a class has an abstract method, or it inherits
    an abstract method that it doesnt override, then
    the class must be declared abstract.
  • public abstract class Employee
  • public abstract double getSalary()
  • // you can mix abstract and non-abstract
    methods
  • // in an abstract class
  • public int getHours() // Note not
    abstract!
  • return 40

59
Abstract Rules (2)
  • If a class is abstract, it cant have a
    constructor.
  • ? No Employee object can be constructed
  • ? But you can declare Employee references.
  • public abstract class Employee
  • public abstract double getSalary()
  • public static void main(String args)
  • Employee e // NO ERROR reference is fine
  • e new Employee() // ERROR! No constructor

60
Extending an abstract class
  • public class Lawyer extends Employee
  • // since Employee declares an abstract
    getSalary,
  • // Lawyer must define getSalary by overriding
    it
  • // or else Lawyer must be an abstract class
  • public double getSalary()
  • return 45000.0
  • public static void main(String args)
  • Employee e // Fine, no problem
  • e new Lawyer() // Also fine (polymorphism)
  • e new Employee() // ERROR! No
    constructor!

61
Abstract classes whats the point?
  • If you cant construct objects for a class,
    whats the point of the class? How can we use
    it?
  • Short Answer polymorphism.
  • We can use references of type Employee as a place
    to store Lawyers, Secretaries, CEOs, etc.
  • Because getSalary() is declared in Employee,
    e.getSalary() is legal syntax, even though
    getSalary() is not defined in Employee.

62
  • P636
  • http//docs.oracle.com/javase/tutorial/java/IandI/
    abstract.html

63
Exercise
  • Create an abstract ClosedShape class with an
    abstract getArea() method
  • Write non-abstract subclasses Rectangle and
    Circle
  • Write main methods for each that construct an
    object and print its area. Do not use attribute
    to store area information.

64
public abstract class Closedshapepublic
abstract double getArea()
public class shapeApp public static void
main(String args) Rectangle r new
Rectangle(2, 3) Circle c new Circle(1.5)
System.out.println(r.getArea())
System.out.println(c.getArea())
public class Circle extends Closedshapeprivate
double radiuspublic Circle (double r)
radius r public double getArea ()return
Math.PIradiusradius public double
getCircumference()return radius
6.07.0685834705770345
public class Rectangle extends Closedshapeprivat
e int length0private int width0public
Rectangle(int l, int w) lengthl
widthw public double getArea ()return
lengthwidth
65
Going full abstract
  • What if our abstract class had no non-abstract
    methods?

public abstract class Employee public
abstract double getSalary() public abstract
int getHours() public abstract String
getVacationForm() Each subclass would have
different definitions. They share only the names
of their methods. Java has an alternative way to
do this interfaces
66
Interfaces
  • Let's say you have the following two related
    classes

public class Scientist public void
discover() System.out.println(Eureka! I have
found it!) public void publish()
System.out.println(My research is better than
yours.)
public class Engineer public void
discover() System.out.println(Cool, what did
I just do?) public void publish()
System.out.println(I don't know how this
happened, but it works.)
  • Neither of their methods do the same thing.

67
Code Reuse
  • But they're still similar they both discover
    and publish. Can we get code reuse?
  • interface Researcher
  • void discover()
  • void publish()
  • Now we can create Researcher references

68
Using Interface Objects
  • public static void researchCycle(Researcher r)
  • r.discover()
  • r.publish()
  • public static void main(String args)
  • Researcher researcher1 new Scientist()
  • Researcher researcher2 new Engineer()
  • // Interfaces have no constructors
  • // They can only be used as types for
    references
  • researcher2 new Researcher() // ERROR!
  • researchCycle(researcher1)
  • researchCycle(researcher2)

69
Using Interfaces
  • Interfaces are a way of specifying what objects
    are capable of, without saying how.
  • Interface variables can execute any of the
    methods listed in the interface, but the behavior
    depends on the class of the object
  • That is, interface variables are polymorphic.
  • There are no constructors for interfaces. They
    are not classes, and no objects of that run-time
    type are created. They are compile-time types
    for references.

70
Implementing Interfaces
  • public class Scientist implements Researcher
  • public void discover()
  • System.out.println(Eureka! I have found
    it!)
  • public void publish()
  • System.out.println(My research is better
    than yours.)

71
  • public class Engineer implements Researcher
  • public void discover()
  • System.out.println(Whoa, what did I just
    do?)
  • public void publish()
  • System.out.println(I don't know how this
    happened, but it
    works.)

72
Exercise
  • Create an interface Measurable class with an
    non-abstract getArea() method
  • Write subclasses Rectangle and Circle to
    implement the above interface
  • Write main methods for each that construct an
    object and print its area. Do not use attribute
    to store area information.

73
public interface Measurablepublic abstract
double getArea()
public class shapeApp public static void
main(String args) Rectangle r new
Rectangle(2, 3) Circle c new Circle(1.5)
System.out.println(r.getArea())
System.out.println(c.getArea())
public class Circle implements Measurableprivate
double radiuspublic Circle (double r)
radius r public double getArea ()return
Math.PIradiusradius public double
getCircumference()return radius
6.07.0685834705770345
public class Rectangle implements
Measurableprivate int length0private int
width0public Rectangle(int l, int w)
lengthl widthw public double getArea
()return lengthwidth
74
public interface Measurablepublic abstract
double getArea()
public class shapeApp public static void
main(String args)// Rectangle r new
Rectangle(2, 3)// Circle c new
Circle(1.5)// System.out.println(r.getArea())
// System.out.println(c.getArea())
Measurable r new Rectangle(2, 3)
//polymorphism display(r) Circle c
new Circle(1.5) Measurable m c
display(m) // (m.getCircumference()) not
allowed Circle t (Circle) m
System.out.println(t.getCircumference())
public class Circle implements Measurableprivate
double radiuspublic Circle (double r)
radius r public double getArea ()return
Math.PIradiusradius public double
getCircumference()return radius
public class Rectangle implements
Measurableprivate int length0private int
width0public Rectangle(int l, int w)
lengthl widthw public double getArea
()return lengthwidth
6.07.0685834705770345 1.5
75
Comparable interface
  • Define the Comparable interface
  • public interface Comparable
  • public int compareTo(Object other)
  • public interface ComparableltTgt
  • public int compareTo(T other)
  • Return a comparable value!

76
  • Fruit.java
  • http//www.cis.temple.edu/jiang/Fruit.pdf
  • FruitDemo.java
  • http//www.cis.temple.edu/jiang/FruitDemo.pdf

77
  • Explanation of interface
  • P612
  • or
  • http//docs.oracle.com/javase/tutorial/java/conce
    pts/interface.html

78
GUI
  • Window interface (p640)
  • www.cis.temple.edu/jiang/ShowButtonDemo.pdf
  • www.cis.temple.edu/jiang/BuktoonDemo.pdf
  • JFrame
  • Basic components
  • Button
  • Event

79
  • Multiple events
  • Label
  • Text field
  • Layouts
  • Other Buttons
  • Color
Write a Comment
User Comments (0)
About PowerShow.com