#1, has planteado una de las cuestiones vitales de la OOP y lo mejor es que has puesto dos buenos trozos de código para enteder las diferencias. Es más, se me ocurre un tercer ejemplo más, pero es tarde ya.
Quizás te parezca que las dos hacen lo mismo (y así es). Pero no lo hacen de la misma forma. Para ver la diferencia, y descubrir una de las bondades de la OOP (hay más), piensa por un momento que en vez de tener dos figuras (triángulo y rectángulo), tuvieras 20 figuras distintas. ¿Cómo sería la clase no abstracta? Enooorme. Y con ello una probabilidad enooorme de tener que retocar la clase más veces y romper el resto del funcionamiento de la clase (aunque te parezca que un switch encapsula el comportamiento).
¿Y si en vez de una única función como la que tienes ahora (area), tuvieras que incorporar 30 funciones más? ¿Cómo de grande sería tu clase y cuántas veces tendrías que tocarla?
Siguiendo en esta línea de tener nuevas funciones:
¿Y si ahora quisieras almacenar en una base de datos tus figuras?
En la solución no-OOP tendrías que implementar en cada 'case' del 'switch' un copy&paste de la función 'GrabarFiguraEnBaseDeDatos'. Con la solución OOP tendrías ese método en la clase abstracta. Y si los datos que guardas son comunes en todas las clases derivadas, entonces podrías implementar ese método en la clase padre y te ahorrarías el copy&paste. ¿Y si un día tienes que tocar esa función que inserta en la base de datos? Pues la tocas una vez y no ochocientas.
¿Y si quisieras realizar operaciones con tus figuras? En la solución no-OOP tendrías que crear dos objetos figura y esas operaciones (funciones) tendría que estar dentro de tu ya mega-clase teniendo que hacer comparaciones entre los tipos de figura.
Con la solución OOP tendrías el método de la operación en la clase abstracta ya que en esa clase se pueden manejar propiedades que tienen en común por ser figuras (su clase padre). Aunque, obviamente la clase padre no ve las implementaciones particulares de las hijas. Sería sólo para propiedades comunes a todas.
Y volviendo a tu primer código no-OOP, ¿y si ahora resulta que la nueva figura no sólo tiene base y altura sino radio porque es un círculo? (típico ejemplo). ¿Modificas el constructor de tu clase figura con ochocientos parámetros? ¿Generas n-constructores distintos por cada figura?
Con la solución OOP, cada clase derivada de la abstracta tiene su propio constructor y llamaría al de la clase padre pasándole sólo aquellas propiedades heredadas y comunes a su padre. Pero la implementación específica la tendría la derivada.
En fin, que estoy escribiendo al tuntun y es tarde y tengo la cabeza embotada. Pero aunque en esos casos te parezca igual, te aseguro que un proyecto gordo de cientos de miles de líneas de código es más fácil tocar en un único sitio que en ochocientos. Y no quiere decir que la OOP sea un camino de rosas. Mal entendida y aplicada se vuelve rígida e inútil. Y uno acaba por hacer un pan con unas ostias al acabar programando de forma estructurada pero creando clases (es lo peor que puedes ver en el mundo real y yo lo he visto! xD).
Todo se resume en: encapsulación, reutilización, pero sobre todo (y esto se descubre con el tiempo) polimorfismo. Bendito polimorfismo la cantidad de copy&paste que ahorra y, por ende, errores.
Si sigues sin entender nada, lo dices e intentamos de nuevo con más ejemplos. Para eso estamos!