data.frames are not depreciated and remain the workhorse of much work in R. With the emergence of "big data" and larger datasets, data.table have become quite useful. Their key advantage is that they have an underlying sorted index, which allows searching by key values and joining (merging) datasets together to be much more efficient and faster. tibbles are helper functions that inherit from data.frame (an affirmation that data.frames are not depricated since tibbles are in fact special forms of data frames).
To illustrate this:
df <- data.frame(a=runif(5),b=runif(5))
tbl <- tibble(a=runif(5),b=runif(5))
The calls to "class" yield:
> class(df)
[1] "data.frame"
> class(tbl)
[1] "tbl_df" "tbl" "data.frame"
This demonstrates that a tibble is itself a data.frame, and therefore any class-related functions will work on tibbles as data.frames (generally, but not always, with a nod to @Spacedman's important clarifications in the comments). The reasons for tibbles are explained in this article: https://cran.r-project.org/web/packages/tibble/vignettes/tibble.html which essentially make them print in a more friendly way on-screen (which is generally irrelevant for embedded/finalized code) and to make some behaviors more consistent; but it may also be argued which behaviors one seeks and prefers if this is a benefit or not.
From the documentation: "Tibbles are a modern take on data frames. They keep the features that have stood the test of time, and drop the features that used to be convenient but are now frustrating (i.e. converting character vectors to factors)." In summary, they are data.frames that offer some convenient shortcuts. (personally, I don't see an incentive to use them in my code--since so many base-R functions and the myriad of libraries out there will return data.frames its certain to need to use data.frames. Which means a preference for tibbles implies intentionally converting data.frames created in other sources into tibbles intentionally and having to manage both in the mental space. For me, it's a lot of overhead to achieve some presumed shortcuts).
For the other aspect of your question, you can use attributes() to see what variables are accessible in the object:
attributes(tbl)
$names
[1] "a" "b"
$row.names
[1] 1 2 3 4 5
$class
[1] "tbl_df" "tbl" "data.frame"